From: Charles Giessen Date: Fri, 22 Mar 2024 16:57:40 +0000 (-0500) Subject: Enhance DriverUnloading tests X-Git-Tag: upstream/1.3.296~72 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cdf8e21a8998ffe094962233b01c944ff378cbc2;p=platform%2Fupstream%2FVulkan-Loader.git Enhance DriverUnloading tests Drivers resize after 32 elements, so to test that path we need to loop over instance level handle creation (surface, debug messenger, debug report). The driver unloading tests needed to create a debug report callback, so that functionality was added to the test framework, modifying VulkanFunctions with a new init function and to make InstWrapper call it when creating an instance. Modify how test_icd_version_7 operates so that by default the functions are exported which is the 'assumed' codepath. This results in a bit of duplication between version 6 & 7, but was kept so as to not modify every test. This also clarifies how a test should enable querying of the functions through vkGetInstanceProcAddr versus exporting those functions (it was combined before). --- diff --git a/tests/framework/framework_config.h.in b/tests/framework/framework_config.h.in index a1b038d9..1857a24c 100644 --- a/tests/framework/framework_config.h.in +++ b/tests/framework/framework_config.h.in @@ -56,7 +56,7 @@ // Version 7 #define TEST_ICD_PATH_VERSION_7 "$" -#define TEST_ICD_PATH_VERSION_7_WITH_ADDITIONAL_EXPORTS "$" +#define TEST_ICD_PATH_VERSION_7_WIHTOUT_EXPORTS "$" // TestLayer binaries #define TEST_LAYER_PATH_EXPORT_BASE "$" diff --git a/tests/framework/icd/CMakeLists.txt b/tests/framework/icd/CMakeLists.txt index 28548ef1..6a7fabb5 100644 --- a/tests/framework/icd/CMakeLists.txt +++ b/tests/framework/icd/CMakeLists.txt @@ -41,11 +41,11 @@ AddSharedLibrary(test_icd_version_6 DEF_FILE test_icd_6 DEFINITIONS TEST_ICD_EXPORT_ICD_GPDPA=1 TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES=1 ${TEST_ICD_VERSION_2_DEFINES}) AddSharedLibrary(test_icd_version_7 DEF_FILE test_icd_7 SOURCES test_icd.cpp - DEFINITIONS TEST_ICD_EXPOSE_VERSION_7=1 ${TEST_ICD_VERSION_2_DEFINES}) -AddSharedLibrary(test_icd_version_7_with_additional_exports DEF_FILE test_icd_7_with_exports + DEFINITIONS TEST_ICD_EXPORT_ICD_GPDPA=1 TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES=1 TEST_ICD_EXPORT_VERSION_7=1 ${TEST_ICD_VERSION_2_DEFINES}) +AddSharedLibrary(test_icd_version_7_without_exports DEF_FILE test_icd_7_without_exports SOURCES test_icd.cpp - DEFINITIONS TEST_ICD_EXPOSE_VERSION_7=1 TEST_ICD_EXPORT_ICD_GPDPA=1 - TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES=1 ${TEST_ICD_VERSION_2_DEFINES}) + DEFINITIONS TEST_ICD_EXPORT_VERSION_7=0 TEST_ICD_EXPORT_ICD_GPDPA=1 + TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES=1 ${TEST_ICD_VERSION_2_DEFINES}) AddSharedLibrary(test_unicode DEF_FILE test_icd_2 SOURCES test_icd.cpp DEFINITIONS ${TEST_ICD_VERSION_2_DEFINES}) diff --git a/tests/framework/icd/export_definitions/test_icd_7.def b/tests/framework/icd/export_definitions/test_icd_7.def index 4414bbea..8cafb296 100644 --- a/tests/framework/icd/export_definitions/test_icd_7.def +++ b/tests/framework/icd/export_definitions/test_icd_7.def @@ -1,3 +1,6 @@ LIBRARY test_icd_version_7 EXPORTS vk_icdGetInstanceProcAddr + vk_icdNegotiateLoaderICDInterfaceVersion + vk_icdEnumerateAdapterPhysicalDevices + vk_icdGetPhysicalDeviceProcAddr diff --git a/tests/framework/icd/export_definitions/test_icd_7_with_exports.def b/tests/framework/icd/export_definitions/test_icd_7_with_exports.def deleted file mode 100644 index 78618057..00000000 --- a/tests/framework/icd/export_definitions/test_icd_7_with_exports.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY test_icd_version_7_with_additional_exports -EXPORTS - vk_icdGetInstanceProcAddr - vk_icdNegotiateLoaderICDInterfaceVersion - vk_icdEnumerateAdapterPhysicalDevices - vk_icdGetPhysicalDeviceProcAddr diff --git a/tests/framework/icd/export_definitions/test_icd_7_without_exports.def b/tests/framework/icd/export_definitions/test_icd_7_without_exports.def new file mode 100644 index 00000000..a6b54191 --- /dev/null +++ b/tests/framework/icd/export_definitions/test_icd_7_without_exports.def @@ -0,0 +1,3 @@ +LIBRARY test_icd_version_7_without_exports +EXPORTS + vk_icdGetInstanceProcAddr diff --git a/tests/framework/icd/test_icd.cpp b/tests/framework/icd/test_icd.cpp index 067fe65f..71637b50 100644 --- a/tests/framework/icd/test_icd.cpp +++ b/tests/framework/icd/test_icd.cpp @@ -49,10 +49,11 @@ #define TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES 0 #endif -// expose vk_icdNegotiateLoaderICDInterfaceVersion, vk_icdEnumerateAdapterPhysicalDevices, and vk_icdGetPhysicalDeviceProcAddr -// through vk_icdGetInstanceProcAddr or vkGetInstanceProcAddr -#if !defined(TEST_ICD_EXPOSE_VERSION_7) -#define TEST_ICD_EXPOSE_VERSION_7 0 +// export vk_icdNegotiateLoaderICDInterfaceVersion, vk_icdEnumerateAdapterPhysicalDevices, and vk_icdGetPhysicalDeviceProcAddr +// through dlsym/GetProcAddress +// Default is *on* +#if !defined(TEST_ICD_EXPORT_VERSION_7) +#define TEST_ICD_EXPORT_VERSION_7 1 #endif TestICD icd; @@ -343,7 +344,7 @@ VKAPI_ATTR void VKAPI_CALL test_vkDestroyDebugUtilsMessengerEXT([[maybe_unused]] // Remove it from the list icd.messenger_handles.erase(found_iter); // Delete the handle - delete (uint8_t*)fake_msgr_handle; + delete (uint8_t*)(fake_msgr_handle); } else { std::cerr << "Messenger not found during destroy!\n"; abort(); @@ -1160,21 +1161,6 @@ VkResult test_vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersi return VK_SUCCESS; } -// Forward declarations for trampolines -extern "C" { -#if TEST_ICD_EXPOSE_VERSION_7 -FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion); -#if TEST_ICD_EXPORT_ICD_GPDPA -FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(VkInstance instance, const char* pName); -#endif -#if defined(WIN32) && TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES -FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vk_icdEnumerateAdapterPhysicalDevices(VkInstance instance, LUID adapterLUID, - uint32_t* pPhysicalDeviceCount, - VkPhysicalDevice* pPhysicalDevices); -#endif -#endif -} - //// trampolines PFN_vkVoidFunction get_instance_func_ver_1_1([[maybe_unused]] VkInstance instance, const char* pName) { @@ -1549,21 +1535,18 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL test_vkGetDeviceProcAddr(VkDevice devic PFN_vkVoidFunction base_get_instance_proc_addr(VkInstance instance, const char* pName) { if (pName == nullptr) return nullptr; if (instance == NULL) { -#if TEST_ICD_EXPOSE_VERSION_7 if (string_eq(pName, "vk_icdNegotiateLoaderICDInterfaceVersion")) return icd.exposes_vk_icdNegotiateLoaderICDInterfaceVersion - ? to_vkVoidFunction(vk_icdNegotiateLoaderICDInterfaceVersion) + ? to_vkVoidFunction(test_vk_icdNegotiateLoaderICDInterfaceVersion) : NULL; -#if TEST_ICD_EXPORT_ICD_GPDPA + if (string_eq(pName, "vk_icdGetPhysicalDeviceProcAddr")) - return icd.exposes_vk_icdGetPhysicalDeviceProcAddr ? to_vkVoidFunction(vk_icdGetPhysicalDeviceProcAddr) : NULL; -#endif -#if defined(WIN32) && TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES + return icd.exposes_vk_icdGetPhysicalDeviceProcAddr ? to_vkVoidFunction(get_physical_device_func) : NULL; +#if defined(WIN32) if (string_eq(pName, "vk_icdEnumerateAdapterPhysicalDevices")) - return icd.exposes_vk_icdEnumerateAdapterPhysicalDevices ? to_vkVoidFunction(vk_icdEnumerateAdapterPhysicalDevices) + return icd.exposes_vk_icdEnumerateAdapterPhysicalDevices ? to_vkVoidFunction(test_vk_icdEnumerateAdapterPhysicalDevices) : NULL; #endif // defined(WIN32) -#endif // TEST_ICD_EXPOSE_VERSION_7 if (string_eq(pName, "vkGetInstanceProcAddr")) return to_vkVoidFunction(test_vkGetInstanceProcAddr); if (string_eq(pName, "vkEnumerateInstanceExtensionProperties")) @@ -1589,13 +1572,13 @@ PFN_vkVoidFunction base_get_instance_proc_addr(VkInstance instance, const char* // Exported functions extern "C" { -#if TEST_ICD_EXPORT_NEGOTIATE_INTERFACE_VERSION +#if TEST_ICD_EXPORT_NEGOTIATE_INTERFACE_VERSION && TEST_ICD_EXPORT_VERSION_7 FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion) { return test_vk_icdNegotiateLoaderICDInterfaceVersion(pSupportedVersion); } #endif // TEST_ICD_EXPORT_NEGOTIATE_INTERFACE_VERSION -#if TEST_ICD_EXPORT_ICD_GPDPA +#if TEST_ICD_EXPORT_ICD_GPDPA && TEST_ICD_EXPORT_VERSION_7 FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(VkInstance instance, const char* pName) { return get_physical_device_func(instance, pName); } @@ -1622,7 +1605,7 @@ FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProp } #endif // TEST_ICD_EXPORT_ICD_GIPA -#if TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES +#if TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES && TEST_ICD_EXPORT_VERSION_7 #if defined(WIN32) FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vk_icdEnumerateAdapterPhysicalDevices(VkInstance instance, LUID adapterLUID, uint32_t* pPhysicalDeviceCount, diff --git a/tests/framework/test_environment.cpp b/tests/framework/test_environment.cpp index cac95d84..ea92868f 100644 --- a/tests/framework/test_environment.cpp +++ b/tests/framework/test_environment.cpp @@ -153,6 +153,13 @@ VulkanFunctions::VulkanFunctions() : loader(get_loader_path()) { init_vulkan_functions(*this); } +void VulkanFunctions::load_instance_functions(VkInstance instance) { + vkCreateDebugReportCallbackEXT = FromVoidStarFunc(vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT")); + vkDestroyDebugReportCallbackEXT = FromVoidStarFunc(vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT")); + vkCreateDebugUtilsMessengerEXT = FromVoidStarFunc(vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT")); + vkDestroyDebugUtilsMessengerEXT = FromVoidStarFunc(vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT")); +} + DeviceFunctions::DeviceFunctions(const VulkanFunctions& vulkan_functions, VkDevice device) { vkGetDeviceProcAddr = vulkan_functions.vkGetDeviceProcAddr; vkDestroyDevice = load(device, "vkDestroyDevice"); @@ -192,10 +199,12 @@ InstWrapper& InstWrapper::operator=(InstWrapper&& other) noexcept { void InstWrapper::CheckCreate(VkResult result_to_check) { ASSERT_EQ(result_to_check, functions->vkCreateInstance(create_info.get(), callbacks, &inst)); + functions->load_instance_functions(inst); } void InstWrapper::CheckCreateWithInfo(InstanceCreateInfo& create_info, VkResult result_to_check) { ASSERT_EQ(result_to_check, functions->vkCreateInstance(create_info.get(), callbacks, &inst)); + functions->load_instance_functions(inst); } std::vector InstWrapper::GetPhysDevs(uint32_t phys_dev_count, VkResult result_to_check) { @@ -292,8 +301,8 @@ void DeviceWrapper::CheckCreate(VkPhysicalDevice phys_dev, VkResult result_to_ch } VkResult CreateDebugUtilsMessenger(DebugUtilsWrapper& debug_utils) { - return debug_utils.vkCreateDebugUtilsMessengerEXT(debug_utils.inst, debug_utils.get(), debug_utils.callbacks, - &debug_utils.messenger); + return debug_utils.local_vkCreateDebugUtilsMessengerEXT(debug_utils.inst, debug_utils.get(), debug_utils.callbacks, + &debug_utils.messenger); } void FillDebugUtilsCreateDetails(InstanceCreateInfo& create_info, DebugUtilsLogger& logger) { @@ -878,6 +887,11 @@ VkResult create_surface(InstWrapper& inst, VkSurfaceKHR& surface, const char* ap return create_surface(inst.functions, inst.inst, surface, api_selection); } +VkResult create_debug_callback(InstWrapper& inst, const VkDebugReportCallbackCreateInfoEXT& create_info, + VkDebugReportCallbackEXT& callback) { + return inst.functions->vkCreateDebugReportCallbackEXT(inst.inst, &create_info, nullptr, &callback); +} + extern "C" { void __ubsan_on_report() { FAIL() << "Encountered an undefined behavior sanitizer error"; } void __asan_on_error() { FAIL() << "Encountered an address sanitizer error"; } diff --git a/tests/framework/test_environment.h b/tests/framework/test_environment.h index 3f6bf519..1be4e480 100644 --- a/tests/framework/test_environment.h +++ b/tests/framework/test_environment.h @@ -167,8 +167,6 @@ struct VulkanFunctions { PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr = nullptr; PFN_vkCreateDevice vkCreateDevice = nullptr; - PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT = nullptr; - PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT = nullptr; // WSI PFN_vkCreateHeadlessSurfaceEXT vkCreateHeadlessSurfaceEXT = nullptr; @@ -231,12 +229,20 @@ struct VulkanFunctions { #endif // VK_USE_PLATFORM_WIN32_KHR PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR = nullptr; + // instance extensions functions (can only be loaded with a valid instance) + PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT = nullptr; // Null unless the extension is enabled + PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT = nullptr; // Null unless the extension is enabled + PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT = nullptr; // Null unless the extension is enabled + PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT = nullptr; // Null unless the extension is enabled + // device functions PFN_vkDestroyDevice vkDestroyDevice = nullptr; PFN_vkGetDeviceQueue vkGetDeviceQueue = nullptr; VulkanFunctions(); + void load_instance_functions(VkInstance instance); + FromVoidStarFunc load(VkInstance inst, const char* func_name) const { return FromVoidStarFunc(vkGetInstanceProcAddr(inst, func_name)); } @@ -338,6 +344,41 @@ struct DeviceWrapper { DeviceCreateInfo create_info{}; }; +template +struct WrappedHandle { + WrappedHandle(HandleType in_handle, ParentType in_parent, DestroyFuncType in_destroy_func, + VkAllocationCallbacks* in_callbacks = nullptr) + : handle(in_handle), parent(in_parent), destroy_func(in_destroy_func), callbacks(in_callbacks) {} + ~WrappedHandle() { + if (handle) { + destroy_func(parent, handle, callbacks); + handle = VK_NULL_HANDLE; + } + } + WrappedHandle(WrappedHandle const&) = delete; + WrappedHandle& operator=(WrappedHandle const&) = delete; + WrappedHandle(WrappedHandle&& other) noexcept + : handle(other.handle), parent(other.parent), destroy_func(other.destroy_func), callbacks(other.callbacks) { + other.handle = VK_NULL_HANDLE; + } + WrappedHandle& operator=(WrappedHandle&& other) noexcept { + if (handle != VK_NULL_HANDLE) { + destroy_func(parent, handle, callbacks); + } + handle = other.handle; + other.handle = VK_NULL_HANDLE; + parent = other.parent; + destroy_func = other.destroy_func; + callbacks = other.callbacks; + return *this; + } + + HandleType handle = VK_NULL_HANDLE; + ParentType parent = VK_NULL_HANDLE; + DestroyFuncType destroy_func = nullptr; + VkAllocationCallbacks* callbacks = nullptr; +}; + struct DebugUtilsLogger { static VkBool32 VKAPI_PTR DebugUtilsMessengerLoggerCallback([[maybe_unused]] VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, @@ -369,6 +410,16 @@ struct DebugUtilsLogger { DebugUtilsLogger& operator=(DebugUtilsLogger&&) = delete; // Find a string in the log output bool find(std::string const& search_text) const { return returned_output.find(search_text) != std::string::npos; } + // Find the number of times a string appears in the log output + uint32_t count(std::string const& search_text) const { + uint32_t occurrences = 0; + std::string::size_type position = 0; + while ((position = returned_output.find(search_text, position)) != std::string::npos) { + ++occurrences; + position += search_text.length(); + } + return occurrences; + } // Look through the event log. If you find a line containing the prefix we're interested in, look for the end of // line character, and then see if the postfix occurs in it as well. @@ -387,15 +438,17 @@ struct DebugUtilsWrapper { VkDebugUtilsMessageSeverityFlagsEXT severity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, VkAllocationCallbacks* callbacks = nullptr) - : logger(severity), inst(inst_wrapper.inst), callbacks(callbacks) { - vkCreateDebugUtilsMessengerEXT = reinterpret_cast( - inst_wrapper.functions->vkGetInstanceProcAddr(inst_wrapper.inst, "vkCreateDebugUtilsMessengerEXT")); - vkDestroyDebugUtilsMessengerEXT = reinterpret_cast( - inst_wrapper.functions->vkGetInstanceProcAddr(inst_wrapper.inst, "vkDestroyDebugUtilsMessengerEXT")); - }; + : logger(severity), + inst(inst_wrapper.inst), + callbacks(callbacks), + local_vkCreateDebugUtilsMessengerEXT( + FromVoidStarFunc(inst_wrapper.functions->vkGetInstanceProcAddr(inst_wrapper.inst, "vkCreateDebugUtilsMessengerEXT"))), + local_vkDestroyDebugUtilsMessengerEXT(FromVoidStarFunc( + inst_wrapper.functions->vkGetInstanceProcAddr(inst_wrapper.inst, "vkDestroyDebugUtilsMessengerEXT"))){}; ~DebugUtilsWrapper() noexcept { if (messenger) { - vkDestroyDebugUtilsMessengerEXT(inst, messenger, callbacks); + local_vkDestroyDebugUtilsMessengerEXT(inst, messenger, callbacks); + messenger = VK_NULL_HANDLE; } } // Immoveable object @@ -405,13 +458,14 @@ struct DebugUtilsWrapper { DebugUtilsWrapper& operator=(DebugUtilsWrapper&&) = delete; bool find(std::string const& search_text) { return logger.find(search_text); } + uint32_t count(std::string const& search_text) { return logger.count(search_text); } VkDebugUtilsMessengerCreateInfoEXT* get() noexcept { return logger.get(); } DebugUtilsLogger logger; VkInstance inst = VK_NULL_HANDLE; VkAllocationCallbacks* callbacks = nullptr; - PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT = nullptr; - PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT = nullptr; + PFN_vkCreateDebugUtilsMessengerEXT local_vkCreateDebugUtilsMessengerEXT = nullptr; + PFN_vkDestroyDebugUtilsMessengerEXT local_vkDestroyDebugUtilsMessengerEXT = nullptr; VkDebugUtilsMessengerEXT messenger = VK_NULL_HANDLE; }; @@ -653,3 +707,6 @@ struct FrameworkEnvironment { VkResult create_surface(InstWrapper& inst, VkSurfaceKHR& out_surface, const char* api_selection = nullptr); // Alternate parameter list for allocation callback tests VkResult create_surface(VulkanFunctions* functions, VkInstance inst, VkSurfaceKHR& surface, const char* api_selection = nullptr); + +VkResult create_debug_callback(InstWrapper& inst, const VkDebugReportCallbackCreateInfoEXT& create_info, + VkDebugReportCallbackEXT& callback); diff --git a/tests/framework/test_util.h b/tests/framework/test_util.h index 1243410f..0a3ac629 100644 --- a/tests/framework/test_util.h +++ b/tests/framework/test_util.h @@ -411,18 +411,20 @@ struct FRAMEWORK_EXPORT DispatchableHandle { handle = reinterpret_cast(ptr_handle); } ~DispatchableHandle() { - delete reinterpret_cast(handle); + if (handle) { + delete reinterpret_cast(handle); + } handle = nullptr; } DispatchableHandle(DispatchableHandle const&) = delete; DispatchableHandle& operator=(DispatchableHandle const&) = delete; DispatchableHandle(DispatchableHandle&& other) noexcept : handle(other.handle) { other.handle = nullptr; } DispatchableHandle& operator=(DispatchableHandle&& other) noexcept { - if (this != &other) { + if (handle) { delete reinterpret_cast(handle); - handle = other.handle; - other.handle = nullptr; } + handle = other.handle; + other.handle = nullptr; return *this; } bool operator==(T base_handle) { return base_handle == handle; } diff --git a/tests/loader_regression_tests.cpp b/tests/loader_regression_tests.cpp index 30004b2e..41b0925c 100644 --- a/tests/loader_regression_tests.cpp +++ b/tests/loader_regression_tests.cpp @@ -4486,7 +4486,7 @@ TEST(EnumerateAdapterPhysicalDevices, WrongErrorCodes) { } #endif // defined(WIN32) -void try_create_swapchain(InstWrapper& inst, VkPhysicalDevice physical_device, DeviceWrapper& dev, VkSurfaceKHR& surface) { +void try_create_swapchain(InstWrapper& inst, VkPhysicalDevice physical_device, DeviceWrapper& dev, VkSurfaceKHR const& surface) { PFN_vkGetPhysicalDeviceSurfaceSupportKHR GetPhysicalDeviceSurfaceSupportKHR = inst.load("vkGetPhysicalDeviceSurfaceSupportKHR"); PFN_vkCreateSwapchainKHR CreateSwapchainKHR = dev.load("vkCreateSwapchainKHR"); PFN_vkGetSwapchainImagesKHR GetSwapchainImagesKHR = dev.load("vkGetSwapchainImagesKHR"); @@ -4537,7 +4537,7 @@ TEST(DriverUnloadingFromZeroPhysDevs, InterspersedThroughout) { DebugUtilsLogger debug_log{VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT}; InstWrapper inst{env.vulkan_functions}; - inst.create_info.setup_WSI(); + inst.create_info.setup_WSI().add_extension("VK_EXT_debug_report"); FillDebugUtilsCreateDetails(inst.create_info, debug_log); inst.CheckCreate(); DebugUtilsWrapper log{inst}; @@ -4546,17 +4546,37 @@ TEST(DriverUnloadingFromZeroPhysDevs, InterspersedThroughout) { PFN_vkSubmitDebugUtilsMessageEXT submit_message = inst.load("vkSubmitDebugUtilsMessageEXT"); ASSERT_TRUE(submit_message != nullptr); + VkSurfaceKHR pre_surface{}; + ASSERT_EQ(VK_SUCCESS, create_surface(inst, pre_surface)); + WrappedHandle pre_enum_phys_devs_surface{ + pre_surface, inst.inst, env.vulkan_functions.vkDestroySurfaceKHR}; + + VkDebugReportCallbackEXT debug_callback{}; + VkDebugReportCallbackCreateInfoEXT debug_report_create_info{}; + ASSERT_EQ(VK_SUCCESS, create_debug_callback(inst, debug_report_create_info, debug_callback)); + WrappedHandle + pre_enum_phys_devs_debug_report_callback{debug_callback, inst.inst, env.vulkan_functions.vkDestroyDebugReportCallbackEXT}; + auto phys_devs = inst.GetPhysDevs(); - VkSurfaceKHR surface{}; - ASSERT_EQ(VK_SUCCESS, create_surface(inst, surface)); + std::vector> messengers; + std::vector> surfaces; + for (uint32_t i = 0; i < 35; i++) { + VkDebugUtilsMessengerEXT messenger; + ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateDebugUtilsMessengerEXT(inst.inst, log.get(), nullptr, &messenger)); + messengers.emplace_back(messenger, inst.inst, env.vulkan_functions.vkDestroyDebugUtilsMessengerEXT); + + VkSurfaceKHR surface{}; + ASSERT_EQ(VK_SUCCESS, create_surface(inst, surface)); + surfaces.emplace_back(surface, inst.inst, env.vulkan_functions.vkDestroySurfaceKHR); + } for (const auto& phys_dev : phys_devs) { DeviceWrapper dev{inst}; dev.create_info.add_extension("VK_KHR_swapchain"); dev.CheckCreate(phys_dev); - - try_create_swapchain(inst, phys_dev, dev, surface); + for (const auto& surface : surfaces) { + try_create_swapchain(inst, phys_dev, dev, surface.handle); + } } - env.vulkan_functions.vkDestroySurfaceKHR(inst.inst, surface, nullptr); } TEST(DriverUnloadingFromZeroPhysDevs, InMiddleOfList) { @@ -4569,22 +4589,42 @@ TEST(DriverUnloadingFromZeroPhysDevs, InMiddleOfList) { InstWrapper inst{env.vulkan_functions}; inst.create_info.add_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); - inst.create_info.setup_WSI(); + inst.create_info.setup_WSI().add_extension("VK_EXT_debug_report"); inst.CheckCreate(); DebugUtilsWrapper log{inst}; ASSERT_EQ(VK_SUCCESS, CreateDebugUtilsMessenger(log)); + VkSurfaceKHR pre_surface{}; + ASSERT_EQ(VK_SUCCESS, create_surface(inst, pre_surface)); + WrappedHandle pre_enum_phys_devs_surface{ + pre_surface, inst.inst, env.vulkan_functions.vkDestroySurfaceKHR}; + + VkDebugReportCallbackEXT debug_callback{}; + VkDebugReportCallbackCreateInfoEXT debug_report_create_info{}; + ASSERT_EQ(VK_SUCCESS, create_debug_callback(inst, debug_report_create_info, debug_callback)); + WrappedHandle + pre_enum_phys_devs_debug_report_callback{debug_callback, inst.inst, env.vulkan_functions.vkDestroyDebugReportCallbackEXT}; + auto phys_devs = inst.GetPhysDevs(); - VkSurfaceKHR surface{}; - ASSERT_EQ(VK_SUCCESS, create_surface(inst, surface)); + std::vector> messengers; + std::vector> surfaces; + for (uint32_t i = 0; i < 35; i++) { + VkDebugUtilsMessengerEXT messenger; + ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateDebugUtilsMessengerEXT(inst.inst, log.get(), nullptr, &messenger)); + messengers.emplace_back(messenger, inst.inst, env.vulkan_functions.vkDestroyDebugUtilsMessengerEXT); + + VkSurfaceKHR surface{}; + ASSERT_EQ(VK_SUCCESS, create_surface(inst, surface)); + surfaces.emplace_back(surface, inst.inst, env.vulkan_functions.vkDestroySurfaceKHR); + } for (const auto& phys_dev : phys_devs) { DeviceWrapper dev{inst}; dev.create_info.add_extension("VK_KHR_swapchain"); dev.CheckCreate(phys_dev); - - try_create_swapchain(inst, phys_dev, dev, surface); + for (const auto& surface : surfaces) { + try_create_swapchain(inst, phys_dev, dev, surface.handle); + } } - env.vulkan_functions.vkDestroySurfaceKHR(inst.inst, surface, nullptr); } TEST(DriverUnloadingFromZeroPhysDevs, AtFrontAndBack) { @@ -4598,26 +4638,48 @@ TEST(DriverUnloadingFromZeroPhysDevs, AtFrontAndBack) { DebugUtilsLogger debug_log{VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT}; InstWrapper inst{env.vulkan_functions}; - inst.create_info.setup_WSI(); + inst.create_info.setup_WSI().add_extension("VK_EXT_debug_report"); FillDebugUtilsCreateDetails(inst.create_info, debug_log); inst.CheckCreate(); + DebugUtilsWrapper log{inst}; ASSERT_EQ(VK_SUCCESS, CreateDebugUtilsMessenger(log)); + VkSurfaceKHR pre_surface{}; + ASSERT_EQ(VK_SUCCESS, create_surface(inst, pre_surface)); + WrappedHandle pre_enum_phys_devs_surface{ + pre_surface, inst.inst, env.vulkan_functions.vkDestroySurfaceKHR}; + + VkDebugReportCallbackEXT debug_callback{}; + VkDebugReportCallbackCreateInfoEXT debug_report_create_info{}; + ASSERT_EQ(VK_SUCCESS, create_debug_callback(inst, debug_report_create_info, debug_callback)); + WrappedHandle + pre_enum_phys_devs_debug_report_callback{debug_callback, inst.inst, env.vulkan_functions.vkDestroyDebugReportCallbackEXT}; + auto phys_devs = inst.GetPhysDevs(); - VkSurfaceKHR surface{}; - ASSERT_EQ(VK_SUCCESS, create_surface(inst, surface)); + std::vector> messengers; + std::vector> surfaces; + for (uint32_t i = 0; i < 35; i++) { + VkDebugUtilsMessengerEXT messenger; + ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateDebugUtilsMessengerEXT(inst.inst, log.get(), nullptr, &messenger)); + messengers.emplace_back(messenger, inst.inst, env.vulkan_functions.vkDestroyDebugUtilsMessengerEXT); + + VkSurfaceKHR surface{}; + ASSERT_EQ(VK_SUCCESS, create_surface(inst, surface)); + surfaces.emplace_back(surface, inst.inst, env.vulkan_functions.vkDestroySurfaceKHR); + } for (const auto& phys_dev : phys_devs) { DeviceWrapper dev{inst}; dev.create_info.add_extension("VK_KHR_swapchain"); dev.CheckCreate(phys_dev); - try_create_swapchain(inst, phys_dev, dev, surface); + for (const auto& surface : surfaces) { + try_create_swapchain(inst, phys_dev, dev, surface.handle); + } } - env.vulkan_functions.vkDestroySurfaceKHR(inst.inst, surface, nullptr); } -TEST(DriverUnloadingFromZeroPhysDevs, NoPhysicaldevices) { +TEST(DriverUnloadingFromZeroPhysDevs, NoPhysicalDevices) { FrameworkEnvironment env{}; add_empty_driver_for_unloading_testing(env); add_empty_driver_for_unloading_testing(env); @@ -4626,16 +4688,110 @@ TEST(DriverUnloadingFromZeroPhysDevs, NoPhysicaldevices) { DebugUtilsLogger debug_log{VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT}; InstWrapper inst{env.vulkan_functions}; - inst.create_info.setup_WSI(); + inst.create_info.setup_WSI().add_extension("VK_EXT_debug_report"); FillDebugUtilsCreateDetails(inst.create_info, debug_log); inst.CheckCreate(); DebugUtilsWrapper log{inst}; ASSERT_EQ(VK_SUCCESS, CreateDebugUtilsMessenger(log)); + + VkSurfaceKHR pre_surface{}; + ASSERT_EQ(VK_SUCCESS, create_surface(inst, pre_surface)); + WrappedHandle pre_enum_phys_devs_surface{ + pre_surface, inst.inst, env.vulkan_functions.vkDestroySurfaceKHR}; + + VkDebugReportCallbackEXT debug_callback{}; + VkDebugReportCallbackCreateInfoEXT debug_report_create_info{}; + ASSERT_EQ(VK_SUCCESS, create_debug_callback(inst, debug_report_create_info, debug_callback)); + WrappedHandle + pre_enum_phys_devs_debug_report_callback{debug_callback, inst.inst, env.vulkan_functions.vkDestroyDebugReportCallbackEXT}; + // No physical devices == VK_ERROR_INITIALIZATION_FAILED inst.GetPhysDevs(VK_ERROR_INITIALIZATION_FAILED); - VkSurfaceKHR surface{}; - ASSERT_EQ(VK_SUCCESS, create_surface(inst, surface)); + std::vector> messengers; + std::vector> surfaces; + for (uint32_t i = 0; i < 35; i++) { + VkDebugUtilsMessengerEXT messenger; + ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateDebugUtilsMessengerEXT(inst.inst, log.get(), nullptr, &messenger)); + messengers.emplace_back(messenger, inst.inst, env.vulkan_functions.vkDestroyDebugUtilsMessengerEXT); + + VkSurfaceKHR surface{}; + ASSERT_EQ(VK_SUCCESS, create_surface(inst, surface)); + surfaces.emplace_back(surface, inst.inst, env.vulkan_functions.vkDestroySurfaceKHR); + } +} + +TEST(DriverUnloadingFromZeroPhysDevs, HandleRecreation) { + FrameworkEnvironment env{}; + add_empty_driver_for_unloading_testing(env); + add_driver_for_unloading_testing(env); + add_empty_driver_for_unloading_testing(env); + add_driver_for_unloading_testing(env); + add_empty_driver_for_unloading_testing(env); + + DebugUtilsLogger debug_log{VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT}; + InstWrapper inst{env.vulkan_functions}; + inst.create_info.setup_WSI().add_extension("VK_EXT_debug_report"); + FillDebugUtilsCreateDetails(inst.create_info, debug_log); + inst.CheckCreate(); + DebugUtilsWrapper log{inst}; + ASSERT_EQ(VK_SUCCESS, CreateDebugUtilsMessenger(log)); + + PFN_vkSubmitDebugUtilsMessageEXT submit_message = inst.load("vkSubmitDebugUtilsMessageEXT"); + ASSERT_TRUE(submit_message != nullptr); + + VkSurfaceKHR pre_surface{}; + ASSERT_EQ(VK_SUCCESS, create_surface(inst, pre_surface)); + WrappedHandle pre_enum_phys_devs_surface{ + pre_surface, inst.inst, env.vulkan_functions.vkDestroySurfaceKHR}; + + VkDebugReportCallbackEXT debug_callback{}; + VkDebugReportCallbackCreateInfoEXT debug_report_create_info{}; + ASSERT_EQ(VK_SUCCESS, create_debug_callback(inst, debug_report_create_info, debug_callback)); + WrappedHandle + pre_enum_phys_devs_debug_report_callback{debug_callback, inst.inst, env.vulkan_functions.vkDestroyDebugReportCallbackEXT}; + + auto phys_devs = inst.GetPhysDevs(); + std::vector> messengers; + std::vector> surfaces; + for (uint32_t i = 0; i < 35; i++) { + VkDebugUtilsMessengerEXT messenger; + ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateDebugUtilsMessengerEXT(inst.inst, log.get(), nullptr, &messenger)); + messengers.emplace_back(messenger, inst.inst, env.vulkan_functions.vkDestroyDebugUtilsMessengerEXT); + + VkSurfaceKHR surface{}; + ASSERT_EQ(VK_SUCCESS, create_surface(inst, surface)); + surfaces.emplace_back(surface, inst.inst, env.vulkan_functions.vkDestroySurfaceKHR); + } + // Remove some elements arbitrarily - remove 15 of each + // Do it backwards so the indexes are 'corect' + for (uint32_t i = 31; i > 2; i -= 2) { + messengers.erase(messengers.begin() + i); + surfaces.erase(surfaces.begin() + i); + } + // Add in another 100 + for (uint32_t i = 0; i < 100; i++) { + VkDebugUtilsMessengerEXT messenger; + ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkCreateDebugUtilsMessengerEXT(inst.inst, log.get(), nullptr, &messenger)); + messengers.emplace_back(messenger, inst.inst, env.vulkan_functions.vkDestroyDebugUtilsMessengerEXT); + + VkSurfaceKHR surface{}; + ASSERT_EQ(VK_SUCCESS, create_surface(inst, surface)); + surfaces.emplace_back(surface, inst.inst, env.vulkan_functions.vkDestroySurfaceKHR); + } + for (const auto& phys_dev : phys_devs) { + DeviceWrapper dev{inst}; + dev.create_info.add_extension("VK_KHR_swapchain"); + dev.CheckCreate(phys_dev); + for (const auto& surface : surfaces) { + try_create_swapchain(inst, phys_dev, dev, surface.handle); + } + } + VkDebugUtilsMessengerCallbackDataEXT data{}; + data.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT; + data.pMessage = "I'm a test message!"; + data.messageIdNumber = 1; + submit_message(inst.inst, VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &data); - env.vulkan_functions.vkDestroySurfaceKHR(inst.inst, surface, nullptr); + ASSERT_EQ(120U + 1U, log.count(data.pMessage)); } diff --git a/tests/loader_version_tests.cpp b/tests/loader_version_tests.cpp index 8307995a..e800d6ac 100644 --- a/tests/loader_version_tests.cpp +++ b/tests/loader_version_tests.cpp @@ -306,7 +306,7 @@ TEST(ICDInterfaceVersion2PlusEnumerateAdapterPhysicalDevices, VerifyGroupResults #endif // defined(WIN32) TEST(ICDInterfaceVersion7, SingleDriver) { FrameworkEnvironment env{}; - auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_7_WITH_ADDITIONAL_EXPORTS)).add_physical_device({}); + auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_7)).add_physical_device({}); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); DeviceWrapper dev{inst}; @@ -316,7 +316,7 @@ TEST(ICDInterfaceVersion7, SingleDriver) { TEST(ICDInterfaceVersion7, SingleDriverWithoutExportedFunctions) { FrameworkEnvironment env{}; - auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_7)).add_physical_device({}); + auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_7_WIHTOUT_EXPORTS)).add_physical_device({}); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); DeviceWrapper dev{inst};