| /* |
| * Copyright (c) 2022 The Khronos Group Inc. |
| * Copyright (c) 2022 Valve Corporation |
| * Copyright (c) 2022 LunarG, Inc. |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a copy |
| * of this software and/or associated documentation files (the "Materials"), to |
| * deal in the Materials without restriction, including without limitation the |
| * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
| * sell copies of the Materials, and to permit persons to whom the Materials are |
| * furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice(s) and this permission notice shall be included in |
| * all copies or substantial portions of the Materials. |
| * |
| * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
| * |
| * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
| * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
| * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE |
| * USE OR OTHER DEALINGS IN THE MATERIALS. |
| * |
| * Author: Charles Giessen <charles@lunarg.com> |
| * Author: Mark Young <marky@lunarg.com> |
| */ |
| |
| #include "test_environment.h" |
| |
| // |
| // VK_EXT_debug_report specific tests |
| // ========================================= |
| // |
| |
| // Prototype declaration for callback so we can use it in class utility methods |
| VkBool32 VKAPI_CALL test_DebugReportCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, |
| size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, |
| void* pUserData); |
| |
| class DebugReportTest : public ::testing::Test { |
| public: |
| void VerifyExpected(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT object_type, const std::string& message) { |
| if (object_type == expected_object_type && 0 < (flags | expected_flag)) { |
| if (allow_any_message || (std::string::npos != message.find(expected_message))) { |
| message_found = true; |
| } |
| } |
| } |
| |
| protected: |
| virtual void SetUp() { |
| env = std::unique_ptr<FrameworkEnvironment>(new FrameworkEnvironment()); |
| for (uint32_t icd = 0; icd < 3; ++icd) { |
| env->add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_0)); |
| env->get_test_icd(icd).physical_devices.push_back({}); |
| env->get_test_icd(icd).physical_devices.push_back({}); |
| } |
| // Initialize the expected output |
| allow_any_message = false; |
| expected_message = ""; |
| expected_object_type = VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT; |
| message_found = false; |
| } |
| |
| VkResult CreateReportInstance(VkDebugReportFlagsEXT debug_report_flags, VkInstance* inst, |
| VkApplicationInfo* app_info = nullptr) { |
| std::vector<const char*> enabled_extensions; |
| enabled_extensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); |
| |
| // Setup the debug report struct |
| VkDebugReportCallbackCreateInfoEXT debug_report_info{VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT}; |
| debug_report_info.pNext = nullptr; |
| debug_report_info.flags = debug_report_flags; |
| debug_report_info.pfnCallback = reinterpret_cast<PFN_vkDebugReportCallbackEXT>(test_DebugReportCallback); |
| debug_report_info.pUserData = reinterpret_cast<void*>(this); |
| |
| // Pass it into instance create struct |
| VkInstanceCreateInfo create_info{}; |
| create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; |
| create_info.pNext = &debug_report_info; |
| create_info.pApplicationInfo = app_info; |
| create_info.enabledExtensionCount = static_cast<uint32_t>(enabled_extensions.size()); |
| create_info.ppEnabledExtensionNames = enabled_extensions.data(); |
| |
| return env->vulkan_functions.vkCreateInstance(&create_info, nullptr, inst); |
| } |
| |
| VkResult CreateReportCallback(VkInstance inst, VkDebugReportFlagsEXT debug_report_flags, VkDebugReportCallbackEXT* callback) { |
| PFN_vkCreateDebugReportCallbackEXT create_debug_report = reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>( |
| env->vulkan_functions.vkGetInstanceProcAddr(inst, "vkCreateDebugReportCallbackEXT")); |
| if (nullptr == create_debug_report) { |
| return VK_ERROR_INITIALIZATION_FAILED; |
| } |
| VkDebugReportCallbackCreateInfoEXT debug_report_info{VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT}; |
| debug_report_info.pNext = nullptr; |
| debug_report_info.flags = debug_report_flags; |
| debug_report_info.pfnCallback = reinterpret_cast<PFN_vkDebugReportCallbackEXT>(test_DebugReportCallback); |
| debug_report_info.pUserData = reinterpret_cast<void*>(this); |
| return create_debug_report(inst, &debug_report_info, nullptr, callback); |
| } |
| |
| VkResult DestroyReportCallback(VkInstance inst, VkDebugReportCallbackEXT callback) { |
| PFN_vkDestroyDebugReportCallbackEXT destroy_debug_report = reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>( |
| env->vulkan_functions.vkGetInstanceProcAddr(inst, "vkDestroyDebugReportCallbackEXT")); |
| if (nullptr == destroy_debug_report) { |
| return VK_ERROR_INITIALIZATION_FAILED; |
| } |
| destroy_debug_report(inst, callback, nullptr); |
| return VK_SUCCESS; |
| } |
| |
| virtual void TearDown() { env.reset(); } |
| |
| std::unique_ptr<FrameworkEnvironment> env; |
| bool allow_any_message; |
| std::string expected_message; |
| VkDebugReportObjectTypeEXT expected_object_type; |
| VkDebugReportFlagBitsEXT expected_flag; |
| bool message_found; |
| }; |
| |
| // This is the actual callback prototyped above. |
| VkBool32 VKAPI_CALL test_DebugReportCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, |
| [[maybe_unused]] uint64_t object, [[maybe_unused]] size_t location, |
| [[maybe_unused]] int32_t messageCode, [[maybe_unused]] const char* pLayerPrefix, |
| const char* pMessage, void* pUserData) { |
| DebugReportTest* debug_report_test = reinterpret_cast<DebugReportTest*>(pUserData); |
| debug_report_test->VerifyExpected(flags, objectType, pMessage); |
| return VK_FALSE; |
| } |
| |
| class CreateDestroyInstanceReport : public DebugReportTest {}; |
| class SeparateReport : public DebugReportTest {}; |
| class ManualReport : public DebugReportTest {}; |
| |
| // Test creating and destroying instance looking for errors, but none should occur. |
| TEST_F(CreateDestroyInstanceReport, NoCallback) { |
| // Make sure we don't find any errors |
| allow_any_message = true; |
| expected_object_type = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT; |
| expected_flag = VK_DEBUG_REPORT_ERROR_BIT_EXT; |
| |
| VkInstance inst = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, CreateReportInstance(VK_DEBUG_REPORT_ERROR_BIT_EXT, &inst)); |
| env->vulkan_functions.vkDestroyInstance(inst, nullptr); |
| |
| ASSERT_EQ(false, message_found); |
| } |
| |
| // Test report (error) created in vkCreateInstance with warning in vkCreateInstance |
| TEST_F(CreateDestroyInstanceReport, WarnInCreateIgnored) { |
| expected_message = "The API Variant specified"; |
| expected_object_type = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT; |
| expected_flag = VK_DEBUG_REPORT_WARNING_BIT_EXT; |
| |
| VkApplicationInfo app_info; |
| app_info.apiVersion = VK_MAKE_API_VERSION(1, 1, 0, 0); |
| VkInstance inst = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, CreateReportInstance(VK_DEBUG_REPORT_ERROR_BIT_EXT, &inst, &app_info)); |
| env->vulkan_functions.vkDestroyInstance(inst, nullptr); |
| |
| // Message should NOT be found (because we only have errors reported in create) |
| ASSERT_EQ(false, message_found); |
| } |
| |
| // Test creating and destroying instance looking for errors, but none should occur. |
| TEST_F(CreateDestroyInstanceReport, WarnInCreate) { |
| expected_message = "The API Variant specified"; |
| expected_object_type = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT; |
| expected_flag = VK_DEBUG_REPORT_WARNING_BIT_EXT; |
| |
| VkApplicationInfo app_info; |
| app_info.apiVersion = VK_MAKE_API_VERSION(1, 1, 0, 0); |
| VkInstance inst = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, CreateReportInstance(VK_DEBUG_REPORT_WARNING_BIT_EXT, &inst, &app_info)); |
| env->vulkan_functions.vkDestroyInstance(inst, nullptr); |
| |
| // Message should be found (because we only have errors reported in create) |
| ASSERT_EQ(true, message_found); |
| } |
| |
| // Test report (error/warning) created in vkCreateInstance with error in vkEnumeratePhysicalDevices. |
| // This should not be logged because we have only defined the debug report logging for vkCreateInstance |
| // and vkDestroyInstance. |
| TEST_F(SeparateReport, ErrorInEnumDevsNoCallback) { |
| // Look for the invaid count param message |
| expected_message = "VUID-vkEnumeratePhysicalDevices-pPhysicalDeviceCount-parameter"; |
| expected_object_type = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT; |
| expected_flag = VK_DEBUG_REPORT_ERROR_BIT_EXT; |
| |
| VkInstance inst = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, CreateReportInstance(VK_DEBUG_REPORT_ERROR_BIT_EXT, &inst)); |
| |
| ASSERT_EQ(env->vulkan_functions.vkEnumeratePhysicalDevices(inst, nullptr, nullptr), VK_ERROR_INITIALIZATION_FAILED); |
| |
| env->vulkan_functions.vkDestroyInstance(inst, nullptr); |
| |
| // Message should NOT be found (because we don't have a report callback setup outside of the create/destroy instance chain) |
| ASSERT_EQ(false, message_found); |
| } |
| |
| // Test report created outside of vkCreateInstance with error in vkEnumeratePhysicalDevices. |
| // This should be logged now. |
| TEST_F(SeparateReport, ErrorInEnumDevs) { |
| // Look for the invaid count param message |
| expected_message = "VUID-vkEnumeratePhysicalDevices-pPhysicalDeviceCount-parameter"; |
| expected_object_type = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT; |
| expected_flag = VK_DEBUG_REPORT_ERROR_BIT_EXT; |
| |
| VkInstance inst = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, CreateReportInstance(VK_DEBUG_REPORT_ERROR_BIT_EXT, &inst)); |
| |
| VkDebugReportCallbackEXT callback; |
| ASSERT_EQ(VK_SUCCESS, CreateReportCallback(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, &callback)); |
| |
| ASSERT_EQ(env->vulkan_functions.vkEnumeratePhysicalDevices(inst, nullptr, nullptr), VK_ERROR_INITIALIZATION_FAILED); |
| |
| ASSERT_EQ(VK_SUCCESS, DestroyReportCallback(inst, callback)); |
| |
| env->vulkan_functions.vkDestroyInstance(inst, nullptr); |
| |
| // Message should be found |
| ASSERT_EQ(true, message_found); |
| } |
| |
| // Test report created outside of vkCreateInstance with info in vkEnumeratePhysicalDevices. |
| // This should not be logged because type is wrong. |
| TEST_F(SeparateReport, InfoInEnumDevsIgnored) { |
| expected_message = "Trimming device count from 6 to 5"; |
| expected_object_type = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT; |
| expected_flag = VK_DEBUG_REPORT_INFORMATION_BIT_EXT; |
| |
| VkInstance inst = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, CreateReportInstance(VK_DEBUG_REPORT_ERROR_BIT_EXT, &inst)); |
| |
| VkDebugReportCallbackEXT callback; |
| ASSERT_EQ(VK_SUCCESS, CreateReportCallback(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, &callback)); |
| |
| uint32_t max_count = 5; |
| std::array<VkPhysicalDevice, 5> devices; |
| ASSERT_EQ(env->vulkan_functions.vkEnumeratePhysicalDevices(inst, &max_count, devices.data()), VK_INCOMPLETE); |
| |
| ASSERT_EQ(VK_SUCCESS, DestroyReportCallback(inst, callback)); |
| |
| env->vulkan_functions.vkDestroyInstance(inst, nullptr); |
| |
| // Message should not be found (because it's info) |
| ASSERT_EQ(false, message_found); |
| } |
| |
| // Test report created outside of vkCreateInstance with info in vkEnumeratePhysicalDevices. |
| // This should be logged because type is correct. |
| TEST_F(SeparateReport, InfoInEnumDevs) { |
| expected_message = "Trimming device count from 6 to 5"; |
| expected_object_type = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT; |
| expected_flag = VK_DEBUG_REPORT_INFORMATION_BIT_EXT; |
| |
| VkInstance inst = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, CreateReportInstance(VK_DEBUG_REPORT_ERROR_BIT_EXT, &inst)); |
| |
| VkDebugReportCallbackEXT callback; |
| ASSERT_EQ(VK_SUCCESS, CreateReportCallback(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, &callback)); |
| |
| uint32_t max_count = 5; |
| std::array<VkPhysicalDevice, 5> devices; |
| ASSERT_EQ(env->vulkan_functions.vkEnumeratePhysicalDevices(inst, &max_count, devices.data()), VK_INCOMPLETE); |
| |
| ASSERT_EQ(VK_SUCCESS, DestroyReportCallback(inst, callback)); |
| |
| env->vulkan_functions.vkDestroyInstance(inst, nullptr); |
| |
| // Message should be found |
| ASSERT_EQ(true, message_found); |
| } |
| |
| // Test report created outside of vkCreateInstance with a manual info message of the wrong message flag type to be logged. |
| TEST_F(ManualReport, InfoIgnoredWrongType) { |
| const char my_message[] = "This is my special message!"; |
| expected_message = my_message; |
| expected_object_type = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT; |
| expected_flag = VK_DEBUG_REPORT_INFORMATION_BIT_EXT; |
| |
| VkInstance inst = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, CreateReportInstance(VK_DEBUG_REPORT_ERROR_BIT_EXT, &inst)); |
| |
| VkDebugReportCallbackEXT callback; |
| ASSERT_EQ(VK_SUCCESS, CreateReportCallback(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, &callback)); |
| |
| PFN_vkDebugReportMessageEXT log_debug_report = |
| reinterpret_cast<PFN_vkDebugReportMessageEXT>(env->vulkan_functions.vkGetInstanceProcAddr(inst, "vkDebugReportMessageEXT")); |
| ASSERT_NE(nullptr, log_debug_report); |
| log_debug_report(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, (uint64_t)(inst), 0, 0, |
| nullptr, my_message); |
| |
| ASSERT_EQ(VK_SUCCESS, DestroyReportCallback(inst, callback)); |
| |
| env->vulkan_functions.vkDestroyInstance(inst, nullptr); |
| |
| // Message should not be found |
| ASSERT_EQ(false, message_found); |
| } |
| |
| // Test report created outside of vkCreateInstance with a manual info message of the wrong object type to be logged. |
| TEST_F(ManualReport, InfoIgnoredWrongObject) { |
| const char my_message[] = "This is my special message!"; |
| expected_message = my_message; |
| expected_object_type = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT; |
| expected_flag = VK_DEBUG_REPORT_INFORMATION_BIT_EXT; |
| |
| VkInstance inst = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, CreateReportInstance(VK_DEBUG_REPORT_ERROR_BIT_EXT, &inst)); |
| |
| VkDebugReportCallbackEXT callback; |
| ASSERT_EQ(VK_SUCCESS, CreateReportCallback(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, &callback)); |
| |
| PFN_vkDebugReportMessageEXT log_debug_report = |
| reinterpret_cast<PFN_vkDebugReportMessageEXT>(env->vulkan_functions.vkGetInstanceProcAddr(inst, "vkDebugReportMessageEXT")); |
| ASSERT_NE(nullptr, log_debug_report); |
| log_debug_report(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, (uint64_t)(inst), 0, 0, |
| nullptr, my_message); |
| |
| ASSERT_EQ(VK_SUCCESS, DestroyReportCallback(inst, callback)); |
| |
| env->vulkan_functions.vkDestroyInstance(inst, nullptr); |
| |
| // Message should not be found |
| ASSERT_EQ(false, message_found); |
| } |
| |
| // Test report created outside of vkCreateInstance with a manual info message to be logged. |
| TEST_F(ManualReport, InfoMessage) { |
| const char my_message[] = "This is my special message!"; |
| expected_message = my_message; |
| expected_object_type = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT; |
| expected_flag = VK_DEBUG_REPORT_INFORMATION_BIT_EXT; |
| |
| VkInstance inst = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, CreateReportInstance(VK_DEBUG_REPORT_ERROR_BIT_EXT, &inst)); |
| |
| VkDebugReportCallbackEXT callback; |
| ASSERT_EQ(VK_SUCCESS, CreateReportCallback(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, &callback)); |
| |
| PFN_vkDebugReportMessageEXT log_debug_report = |
| reinterpret_cast<PFN_vkDebugReportMessageEXT>(env->vulkan_functions.vkGetInstanceProcAddr(inst, "vkDebugReportMessageEXT")); |
| ASSERT_NE(nullptr, log_debug_report); |
| log_debug_report(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, (uint64_t)(inst), 0, 0, |
| nullptr, my_message); |
| |
| ASSERT_EQ(VK_SUCCESS, DestroyReportCallback(inst, callback)); |
| |
| env->vulkan_functions.vkDestroyInstance(inst, nullptr); |
| |
| // Message should be found |
| ASSERT_EQ(true, message_found); |
| } |
| |
| // |
| // VK_EXT_debug_util specific tests |
| // ========================================= |
| // |
| |
| // Prototype declaration for callback so we can use it in class utility methods |
| VkBool32 VKAPI_CALL test_DebugUtilsCallback(VkDebugUtilsMessageSeverityFlagBitsEXT message_severity, |
| VkDebugUtilsMessageTypeFlagsEXT message_types, |
| const VkDebugUtilsMessengerCallbackDataEXT* callback_data, void* user_data); |
| |
| class DebugUtilTest : public ::testing::Test { |
| public: |
| void VerifyExpected(VkDebugUtilsMessageTypeFlagsEXT message_flags, VkDebugUtilsMessageSeverityFlagsEXT severity_flags, |
| const std::string& message, const VkDebugUtilsMessengerCallbackDataEXT* callback_data) { |
| if ((0 < (severity_flags | expected_severity_flags)) && (0 < (message_flags | expected_message_flags))) { |
| if (allow_any_message || (std::string::npos != message.find(expected_message))) { |
| for (uint32_t obj = 0; obj < callback_data->objectCount; ++obj) { |
| if (callback_data->pObjects[obj].objectType == expected_object_type && |
| (!check_object_handle || callback_data->pObjects[obj].objectHandle == expected_object_handle)) { |
| message_found = true; |
| break; |
| } |
| } |
| } |
| } |
| } |
| |
| protected: |
| virtual void SetUp() { |
| env = std::unique_ptr<FrameworkEnvironment>(new FrameworkEnvironment()); |
| for (uint32_t icd = 0; icd < 3; ++icd) { |
| env->add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_0)); |
| env->get_test_icd(icd).physical_devices.push_back({}); |
| env->get_test_icd(icd).physical_devices.push_back({}); |
| } |
| // Initialize the expected output |
| allow_any_message = false; |
| expected_message = ""; |
| expected_object_type = VK_OBJECT_TYPE_UNKNOWN; |
| check_object_handle = false; |
| expected_object_handle = 0; |
| message_found = false; |
| } |
| |
| VkResult CreateUtilsInstance(VkDebugUtilsMessageTypeFlagsEXT types, VkDebugUtilsMessageSeverityFlagsEXT severities, |
| VkInstance* inst, VkApplicationInfo* app_info = nullptr) { |
| std::vector<const char*> enabled_extensions; |
| enabled_extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); |
| |
| // Setup the debug utils struct |
| VkDebugUtilsMessengerCreateInfoEXT debug_utils_info{VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT}; |
| debug_utils_info.pNext = nullptr; |
| debug_utils_info.messageSeverity = severities; |
| debug_utils_info.messageType = types; |
| debug_utils_info.pfnUserCallback = reinterpret_cast<PFN_vkDebugUtilsMessengerCallbackEXT>(test_DebugUtilsCallback); |
| debug_utils_info.pUserData = reinterpret_cast<void*>(this); |
| |
| VkInstanceCreateInfo create_info{}; |
| create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; |
| create_info.pNext = &debug_utils_info; |
| create_info.pApplicationInfo = app_info; |
| create_info.enabledExtensionCount = static_cast<uint32_t>(enabled_extensions.size()); |
| create_info.ppEnabledExtensionNames = enabled_extensions.data(); |
| return env->vulkan_functions.vkCreateInstance(&create_info, nullptr, inst); |
| } |
| |
| VkResult CreateUtilsMessenger(VkInstance inst, VkDebugUtilsMessageTypeFlagsEXT types, |
| VkDebugUtilsMessageSeverityFlagsEXT severities, VkDebugUtilsMessengerEXT* messenger) { |
| PFN_vkCreateDebugUtilsMessengerEXT create_messenger = reinterpret_cast<PFN_vkCreateDebugUtilsMessengerEXT>( |
| env->vulkan_functions.vkGetInstanceProcAddr(inst, "vkCreateDebugUtilsMessengerEXT")); |
| if (nullptr == create_messenger) { |
| return VK_ERROR_INITIALIZATION_FAILED; |
| } |
| VkDebugUtilsMessengerCreateInfoEXT debug_utils_info{VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT}; |
| debug_utils_info.pNext = nullptr; |
| debug_utils_info.messageSeverity = severities; |
| debug_utils_info.messageType = types; |
| debug_utils_info.pfnUserCallback = reinterpret_cast<PFN_vkDebugUtilsMessengerCallbackEXT>(test_DebugUtilsCallback); |
| debug_utils_info.pUserData = reinterpret_cast<void*>(this); |
| return create_messenger(inst, &debug_utils_info, nullptr, messenger); |
| } |
| |
| VkResult DestroyUtilsMessenger(VkInstance inst, VkDebugUtilsMessengerEXT messenger) { |
| PFN_vkDestroyDebugUtilsMessengerEXT destroy_messenger = reinterpret_cast<PFN_vkDestroyDebugUtilsMessengerEXT>( |
| env->vulkan_functions.vkGetInstanceProcAddr(inst, "vkDestroyDebugUtilsMessengerEXT")); |
| if (nullptr == destroy_messenger) { |
| return VK_ERROR_INITIALIZATION_FAILED; |
| } |
| destroy_messenger(inst, messenger, nullptr); |
| return VK_SUCCESS; |
| } |
| |
| virtual void TearDown() { env.reset(); } |
| |
| std::unique_ptr<FrameworkEnvironment> env; |
| bool allow_any_message; |
| std::string expected_message; |
| VkObjectType expected_object_type; |
| bool check_object_handle; |
| uint64_t expected_object_handle; |
| VkDebugUtilsMessageTypeFlagsEXT expected_message_flags; |
| VkDebugUtilsMessageSeverityFlagsEXT expected_severity_flags; |
| bool message_found; |
| }; |
| |
| // This is the actual callback prototyped above. |
| |
| VkBool32 VKAPI_CALL test_DebugUtilsCallback(VkDebugUtilsMessageSeverityFlagBitsEXT message_severity, |
| VkDebugUtilsMessageTypeFlagsEXT message_types, |
| const VkDebugUtilsMessengerCallbackDataEXT* callback_data, void* user_data) { |
| DebugUtilTest* debug_util_test = reinterpret_cast<DebugUtilTest*>(user_data); |
| debug_util_test->VerifyExpected(message_types, message_severity, callback_data->pMessage, callback_data); |
| return VK_FALSE; |
| } |
| |
| class CreateDestroyInstanceMessenger : public DebugUtilTest {}; |
| class SeparateMessenger : public DebugUtilTest {}; |
| class ManualMessage : public DebugUtilTest {}; |
| |
| // Test creating and destroying instance looking for errors, but none should occur. |
| TEST_F(CreateDestroyInstanceMessenger, NoCallback) { |
| // Make sure we don't find any errors |
| allow_any_message = true; |
| expected_object_type = VK_OBJECT_TYPE_INSTANCE; |
| expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT; |
| expected_severity_flags = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; |
| |
| VkInstance inst = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, |
| CreateUtilsInstance(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, |
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, &inst)); |
| env->vulkan_functions.vkDestroyInstance(inst, nullptr); |
| |
| ASSERT_EQ(false, message_found); |
| } |
| |
| // Test debug utils (error) created in vkCreateInstance with warning in vkCreateInstance |
| TEST_F(CreateDestroyInstanceMessenger, WarnInCreateIgnored) { |
| expected_message = "The API Variant specified"; |
| expected_object_type = VK_OBJECT_TYPE_INSTANCE; |
| expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT; |
| expected_severity_flags = VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT; |
| |
| VkApplicationInfo app_info; |
| app_info.apiVersion = VK_MAKE_API_VERSION(1, 1, 0, 0); |
| |
| VkInstance inst = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, CreateUtilsInstance(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, |
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, &inst, &app_info)); |
| env->vulkan_functions.vkDestroyInstance(inst, nullptr); |
| |
| ASSERT_EQ(false, message_found); |
| } |
| |
| // Test debug utils (error/warning) created in vkCreateInstance with warning in vkCreateInstance |
| TEST_F(CreateDestroyInstanceMessenger, WarnInCreate) { |
| expected_message = "The API Variant specified"; |
| expected_object_type = VK_OBJECT_TYPE_INSTANCE; |
| expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT; |
| expected_severity_flags = VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT; |
| |
| VkApplicationInfo app_info; |
| app_info.apiVersion = VK_MAKE_API_VERSION(1, 1, 0, 0); |
| |
| VkInstance inst = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, CreateUtilsInstance(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, |
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT, &inst, &app_info)); |
| env->vulkan_functions.vkDestroyInstance(inst, nullptr); |
| |
| ASSERT_EQ(true, message_found); |
| } |
| |
| // Test debug utils error created in vkCreateInstance with error in vkEnumeratePhysicalDevices. |
| // This should not be logged because we have only defined the debug utils logging for vkCreateInstance |
| // and vkDestroyInstance. |
| TEST_F(SeparateMessenger, ErrorInEnumDevsNoMessenger) { |
| expected_message = "VUID-vkEnumeratePhysicalDevices-pPhysicalDeviceCount-parameter"; |
| expected_object_type = VK_OBJECT_TYPE_INSTANCE; |
| expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT; |
| expected_severity_flags = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; |
| |
| VkInstance inst = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, |
| CreateUtilsInstance(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, |
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, &inst)); |
| |
| ASSERT_EQ(env->vulkan_functions.vkEnumeratePhysicalDevices(inst, nullptr, nullptr), VK_ERROR_INITIALIZATION_FAILED); |
| |
| env->vulkan_functions.vkDestroyInstance(inst, nullptr); |
| |
| // Message should NOT be found (because we don't have a report callback setup outside of the create/destroy instance chain) |
| ASSERT_EQ(false, message_found); |
| } |
| |
| // Test debug utils created outside of vkCreateInstance with error in vkEnumeratePhysicalDevices, but, with the wrong |
| // message type so it still won't be logged. |
| TEST_F(SeparateMessenger, ErrorInEnumDevsWrongType) { |
| expected_message = "VUID-vkEnumeratePhysicalDevices-pPhysicalDeviceCount-parameter"; |
| expected_object_type = VK_OBJECT_TYPE_INSTANCE; |
| expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT; |
| expected_severity_flags = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; |
| |
| VkInstance inst = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, |
| CreateUtilsInstance(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, |
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, &inst)); |
| |
| // Create the debug utils messenger to collect performance warnings and errors |
| VkDebugUtilsMessengerEXT messenger = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, |
| CreateUtilsMessenger(inst, VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, |
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT, |
| &messenger)); |
| |
| ASSERT_EQ(env->vulkan_functions.vkEnumeratePhysicalDevices(inst, nullptr, nullptr), VK_ERROR_INITIALIZATION_FAILED); |
| |
| // Now that we should have gotten our message, destroy the messenger |
| ASSERT_EQ(VK_SUCCESS, DestroyUtilsMessenger(inst, messenger)); |
| |
| env->vulkan_functions.vkDestroyInstance(inst, nullptr); |
| |
| ASSERT_EQ(false, message_found); |
| } |
| |
| // Test debug utils created outside of vkCreateInstance with error in vkEnumeratePhysicalDevices, but, with the wrong |
| // message severity so it still won't be logged. |
| TEST_F(SeparateMessenger, ErrorInEnumDevsWrongSeverity) { |
| expected_message = "VUID-vkEnumeratePhysicalDevices-pPhysicalDeviceCount-parameter"; |
| expected_object_type = VK_OBJECT_TYPE_INSTANCE; |
| expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT; |
| expected_severity_flags = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; |
| |
| VkInstance inst = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, |
| CreateUtilsInstance(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, |
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, &inst)); |
| |
| // Create the debug utils messenger to collect only validation warnings |
| VkDebugUtilsMessengerEXT messenger = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, CreateUtilsMessenger(inst, VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, |
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT, &messenger)); |
| |
| ASSERT_EQ(env->vulkan_functions.vkEnumeratePhysicalDevices(inst, nullptr, nullptr), VK_ERROR_INITIALIZATION_FAILED); |
| |
| // Now that we should have gotten our message, destroy the messenger |
| ASSERT_EQ(VK_SUCCESS, DestroyUtilsMessenger(inst, messenger)); |
| |
| env->vulkan_functions.vkDestroyInstance(inst, nullptr); |
| |
| ASSERT_EQ(false, message_found); |
| } |
| |
| // Test debug utils created outside of vkCreateInstance with error in vkEnumeratePhysicalDevices with the correct type. |
| TEST_F(SeparateMessenger, ErrorInEnumDevs) { |
| expected_message = "VUID-vkEnumeratePhysicalDevices-pPhysicalDeviceCount-parameter"; |
| expected_object_type = VK_OBJECT_TYPE_INSTANCE; |
| expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT; |
| expected_severity_flags = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; |
| |
| VkInstance inst = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, |
| CreateUtilsInstance(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, |
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, &inst)); |
| |
| // Create the debug utils messenger to collect validation errors |
| VkDebugUtilsMessengerEXT messenger = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, CreateUtilsMessenger(inst, VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, |
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, &messenger)); |
| |
| ASSERT_EQ(env->vulkan_functions.vkEnumeratePhysicalDevices(inst, nullptr, nullptr), VK_ERROR_INITIALIZATION_FAILED); |
| |
| // Now that we should have gotten our message, destroy the messenger |
| ASSERT_EQ(VK_SUCCESS, DestroyUtilsMessenger(inst, messenger)); |
| |
| env->vulkan_functions.vkDestroyInstance(inst, nullptr); |
| |
| ASSERT_EQ(true, message_found); |
| } |
| |
| // Test debug utils created outside of vkCreateInstance with info in vkEnumeratePhysicalDevices. |
| // This should not be logged because type is wrong. |
| TEST_F(SeparateMessenger, InfoInEnumDevsIgnoredType) { |
| expected_message = "Trimming device count from 6 to 5"; |
| expected_object_type = VK_OBJECT_TYPE_INSTANCE; |
| expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT; |
| expected_severity_flags = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT; |
| |
| VkInstance inst = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, |
| CreateUtilsInstance(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, |
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, &inst)); |
| |
| // Create the debug utils messenger to collect validation info |
| VkDebugUtilsMessengerEXT messenger = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, CreateUtilsMessenger(inst, VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, |
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, &messenger)); |
| |
| uint32_t max_count = 5; |
| std::array<VkPhysicalDevice, 5> devices; |
| ASSERT_EQ(env->vulkan_functions.vkEnumeratePhysicalDevices(inst, &max_count, devices.data()), VK_INCOMPLETE); |
| |
| // Now that we should have gotten our message, destroy the messenger |
| ASSERT_EQ(VK_SUCCESS, DestroyUtilsMessenger(inst, messenger)); |
| |
| env->vulkan_functions.vkDestroyInstance(inst, nullptr); |
| |
| // Message should not be found (because it's info) |
| ASSERT_EQ(false, message_found); |
| } |
| |
| // Test debug utils created outside of vkCreateInstance with info in vkEnumeratePhysicalDevices. |
| // This should not be logged because severity is wrong. |
| TEST_F(SeparateMessenger, InfoInEnumDevsIgnoredSeverity) { |
| expected_message = "Trimming device count from 6 to 5"; |
| expected_object_type = VK_OBJECT_TYPE_INSTANCE; |
| expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT; |
| expected_severity_flags = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT; |
| |
| VkInstance inst = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, |
| CreateUtilsInstance(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, |
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, &inst)); |
| |
| // Create the debug utils messenger to collect general errors/warnings |
| VkDebugUtilsMessengerEXT messenger = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, |
| CreateUtilsMessenger(inst, VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, |
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT, |
| &messenger)); |
| |
| uint32_t max_count = 5; |
| std::array<VkPhysicalDevice, 5> devices; |
| ASSERT_EQ(env->vulkan_functions.vkEnumeratePhysicalDevices(inst, &max_count, devices.data()), VK_INCOMPLETE); |
| |
| // Now that we should have gotten our message, destroy the messenger |
| ASSERT_EQ(VK_SUCCESS, DestroyUtilsMessenger(inst, messenger)); |
| |
| env->vulkan_functions.vkDestroyInstance(inst, nullptr); |
| |
| // Message should not be found (because it's info) |
| ASSERT_EQ(false, message_found); |
| } |
| |
| // Test debug utils created outside of vkCreateInstance with info in vkEnumeratePhysicalDevices. |
| TEST_F(SeparateMessenger, InfoInEnumDevs) { |
| expected_message = "Trimming device count from 6 to 5"; |
| expected_object_type = VK_OBJECT_TYPE_INSTANCE; |
| expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT; |
| expected_severity_flags = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT; |
| |
| VkInstance inst = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, |
| CreateUtilsInstance(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, |
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, &inst)); |
| ASSERT_EQ(false, message_found); |
| |
| // Create the debug utils messenger to collect general errors/warnings |
| VkDebugUtilsMessengerEXT messenger = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, CreateUtilsMessenger(inst, VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, |
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, &messenger)); |
| |
| uint32_t max_count = 5; |
| std::array<VkPhysicalDevice, 5> devices; |
| ASSERT_EQ(env->vulkan_functions.vkEnumeratePhysicalDevices(inst, &max_count, devices.data()), VK_INCOMPLETE); |
| |
| // Now that we should have gotten our message, destroy the messenger |
| ASSERT_EQ(VK_SUCCESS, DestroyUtilsMessenger(inst, messenger)); |
| |
| env->vulkan_functions.vkDestroyInstance(inst, nullptr); |
| |
| // Message should be found |
| ASSERT_EQ(true, message_found); |
| } |
| |
| // Test messenger created outside of vkCreateInstance with a manual info message of the wrong message severity to be logged. |
| TEST_F(ManualMessage, InfoMessageIgnoredSeverity) { |
| const char my_message[] = "This is my special message!"; |
| expected_message = my_message; |
| expected_object_type = VK_OBJECT_TYPE_INSTANCE; |
| expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT; |
| expected_severity_flags = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT; |
| |
| VkInstance inst = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, CreateUtilsInstance(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, |
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, &inst)); |
| |
| // Create the debug utils messenger to collect general errors/warnings |
| VkDebugUtilsMessengerEXT messenger = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, |
| CreateUtilsMessenger(inst, VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, |
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT, |
| &messenger)); |
| |
| // Trigger the message |
| PFN_vkSubmitDebugUtilsMessageEXT submit_message = reinterpret_cast<PFN_vkSubmitDebugUtilsMessageEXT>( |
| env->vulkan_functions.vkGetInstanceProcAddr(inst, "vkSubmitDebugUtilsMessageEXT")); |
| ASSERT_NE(nullptr, submit_message); |
| |
| VkDebugUtilsObjectNameInfoEXT object{VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT}; |
| object.objectType = VK_OBJECT_TYPE_INSTANCE; |
| object.objectHandle = (uint64_t)inst; |
| VkDebugUtilsMessengerCallbackDataEXT message_data{VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT}; |
| message_data.pMessage = my_message; |
| message_data.objectCount = 1; |
| message_data.pObjects = &object; |
| submit_message(inst, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &message_data); |
| |
| // Now that we should have gotten our message, destroy the messenger |
| ASSERT_EQ(VK_SUCCESS, DestroyUtilsMessenger(inst, messenger)); |
| |
| env->vulkan_functions.vkDestroyInstance(inst, nullptr); |
| |
| // Message should not be found |
| ASSERT_EQ(false, message_found); |
| } |
| |
| // Test messenger created outside of vkCreateInstance with a manual info message of the wrong object type to be logged. |
| TEST_F(ManualMessage, InfoMessageIgnoredObject) { |
| const char my_message[] = "This is my special message!"; |
| expected_message = my_message; |
| expected_object_type = VK_OBJECT_TYPE_INSTANCE; |
| expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT; |
| expected_severity_flags = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT; |
| |
| VkInstance inst = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, CreateUtilsInstance(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, |
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, &inst)); |
| |
| // Create the debug utils messenger to collect general errors/warnings |
| VkDebugUtilsMessengerEXT messenger = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, CreateUtilsMessenger(inst, VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, |
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, &messenger)); |
| |
| // Trigger the message |
| PFN_vkSubmitDebugUtilsMessageEXT submit_message = reinterpret_cast<PFN_vkSubmitDebugUtilsMessageEXT>( |
| env->vulkan_functions.vkGetInstanceProcAddr(inst, "vkSubmitDebugUtilsMessageEXT")); |
| ASSERT_NE(nullptr, submit_message); |
| |
| VkDebugUtilsObjectNameInfoEXT object{VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT}; |
| object.objectType = VK_OBJECT_TYPE_COMMAND_POOL; |
| object.objectHandle = (uint64_t)inst; |
| VkDebugUtilsMessengerCallbackDataEXT message_data{VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT}; |
| message_data.pMessage = my_message; |
| message_data.objectCount = 1; |
| message_data.pObjects = &object; |
| submit_message(inst, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &message_data); |
| |
| // Now that we should have gotten our message, destroy the messenger |
| ASSERT_EQ(VK_SUCCESS, DestroyUtilsMessenger(inst, messenger)); |
| |
| env->vulkan_functions.vkDestroyInstance(inst, nullptr); |
| |
| // Message should not be found |
| ASSERT_EQ(false, message_found); |
| } |
| |
| // Test messenger created outside of vkCreateInstance with a manual info message. |
| TEST_F(ManualMessage, InfoMessage) { |
| const char my_message[] = "This is my special message!"; |
| expected_message = my_message; |
| expected_object_type = VK_OBJECT_TYPE_INSTANCE; |
| expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT; |
| expected_severity_flags = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT; |
| |
| VkInstance inst = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, CreateUtilsInstance(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, |
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, &inst)); |
| |
| // Create the debug utils messenger to collect general errors/warnings |
| VkDebugUtilsMessengerEXT messenger = VK_NULL_HANDLE; |
| ASSERT_EQ(VK_SUCCESS, CreateUtilsMessenger(inst, VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, |
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, &messenger)); |
| |
| // Trigger the message |
| PFN_vkSubmitDebugUtilsMessageEXT submit_message = reinterpret_cast<PFN_vkSubmitDebugUtilsMessageEXT>( |
| env->vulkan_functions.vkGetInstanceProcAddr(inst, "vkSubmitDebugUtilsMessageEXT")); |
| ASSERT_NE(nullptr, submit_message); |
| |
| VkDebugUtilsObjectNameInfoEXT object{VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT}; |
| object.objectType = VK_OBJECT_TYPE_INSTANCE; |
| object.objectHandle = (uint64_t)inst; |
| VkDebugUtilsMessengerCallbackDataEXT message_data{VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT}; |
| message_data.pMessage = my_message; |
| message_data.objectCount = 1; |
| message_data.pObjects = &object; |
| submit_message(inst, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &message_data); |
| |
| // Now that we should have gotten our message, destroy the messenger |
| ASSERT_EQ(VK_SUCCESS, DestroyUtilsMessenger(inst, messenger)); |
| |
| env->vulkan_functions.vkDestroyInstance(inst, nullptr); |
| |
| // Message should be found |
| ASSERT_EQ(true, message_found); |
| } |
| |
| void CheckDeviceFunctions(FrameworkEnvironment& env, bool use_GIPA, bool enable_debug_extensions, |
| bool hardware_supports_debug_exts) { |
| InstWrapper inst(env.vulkan_functions); |
| if (enable_debug_extensions) { |
| inst.create_info.add_extension("VK_EXT_debug_utils"); |
| inst.create_info.add_extension("VK_EXT_debug_report"); |
| } |
| inst.create_info.setup_WSI(); |
| 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 (enable_debug_extensions && !hardware_supports_debug_exts) { |
| // 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 |
| |
| dev.CheckCreate(phys_dev, VK_ERROR_EXTENSION_NOT_PRESENT); |
| return; |
| } else { |
| ASSERT_NO_FATAL_FAILURE(dev.CheckCreate(phys_dev)); |
| } |
| DeviceFunctions dev_funcs{env.vulkan_functions, dev}; |
| |
| VkSurfaceKHR surface{}; |
| ASSERT_EQ(VK_SUCCESS, 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)); |
| |
| auto load_function = [&inst, &dev, use_GIPA](const char* func_name) { |
| return use_GIPA ? inst.load(func_name) : dev.load(func_name); |
| }; |
| |
| // Debug marker |
| PFN_vkDebugMarkerSetObjectTagEXT DebugMarkerSetObjectTagEXT = load_function("vkDebugMarkerSetObjectTagEXT"); |
| PFN_vkDebugMarkerSetObjectNameEXT DebugMarkerSetObjectNameEXT = load_function("vkDebugMarkerSetObjectNameEXT"); |
| PFN_vkCmdDebugMarkerBeginEXT CmdDebugMarkerBeginEXT = load_function("vkCmdDebugMarkerBeginEXT"); |
| PFN_vkCmdDebugMarkerEndEXT CmdDebugMarkerEndEXT = load_function("vkCmdDebugMarkerEndEXT"); |
| PFN_vkCmdDebugMarkerInsertEXT CmdDebugMarkerInsertEXT = load_function("vkCmdDebugMarkerInsertEXT"); |
| // Debug utils |
| PFN_vkSetDebugUtilsObjectNameEXT SetDebugUtilsObjectNameEXT = load_function("vkSetDebugUtilsObjectNameEXT"); |
| PFN_vkSetDebugUtilsObjectTagEXT SetDebugUtilsObjectTagEXT = load_function("vkSetDebugUtilsObjectTagEXT"); |
| PFN_vkQueueBeginDebugUtilsLabelEXT QueueBeginDebugUtilsLabelEXT = load_function("vkQueueBeginDebugUtilsLabelEXT"); |
| PFN_vkQueueEndDebugUtilsLabelEXT QueueEndDebugUtilsLabelEXT = load_function("vkQueueEndDebugUtilsLabelEXT"); |
| PFN_vkQueueInsertDebugUtilsLabelEXT QueueInsertDebugUtilsLabelEXT = load_function("vkQueueInsertDebugUtilsLabelEXT"); |
| PFN_vkCmdBeginDebugUtilsLabelEXT CmdBeginDebugUtilsLabelEXT = load_function("vkCmdBeginDebugUtilsLabelEXT"); |
| PFN_vkCmdEndDebugUtilsLabelEXT CmdEndDebugUtilsLabelEXT = load_function("vkCmdEndDebugUtilsLabelEXT"); |
| PFN_vkCmdInsertDebugUtilsLabelEXT CmdInsertDebugUtilsLabelEXT = load_function("vkCmdInsertDebugUtilsLabelEXT"); |
| |
| // Debug marker functions - should always be found when using GIPA but when using GDPA found only when the extension is enabled |
| if (use_GIPA) { |
| ASSERT_TRUE(nullptr != DebugMarkerSetObjectTagEXT); |
| ASSERT_TRUE(nullptr != DebugMarkerSetObjectNameEXT); |
| ASSERT_TRUE(nullptr != CmdDebugMarkerBeginEXT); |
| ASSERT_TRUE(nullptr != CmdDebugMarkerEndEXT); |
| ASSERT_TRUE(nullptr != CmdDebugMarkerInsertEXT); |
| } else { |
| ASSERT_EQ(enable_debug_extensions, nullptr != DebugMarkerSetObjectTagEXT); |
| ASSERT_EQ(enable_debug_extensions, nullptr != DebugMarkerSetObjectNameEXT); |
| ASSERT_EQ(enable_debug_extensions, nullptr != CmdDebugMarkerBeginEXT); |
| ASSERT_EQ(enable_debug_extensions, nullptr != CmdDebugMarkerEndEXT); |
| ASSERT_EQ(enable_debug_extensions, nullptr != CmdDebugMarkerInsertEXT); |
| } |
| |
| // Debug utils functions - should only be found if the extension was enabled (because its instance level) |
| 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); |
| |
| if (SetDebugUtilsObjectNameEXT) { |
| 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!"; |
| ASSERT_EQ(VK_SUCCESS, SetDebugUtilsObjectNameEXT(dev.dev, &obj_name_info)); |
| |
| obj_name_info.objectHandle = (uint64_t)(uintptr_t)surface; |
| obj_name_info.objectType = VK_OBJECT_TYPE_SURFACE_KHR; |
| obj_name_info.pObjectName = " Your moms surface!"; |
| ASSERT_EQ(VK_SUCCESS, SetDebugUtilsObjectNameEXT(dev.dev, &obj_name_info)); |
| |
| obj_name_info.objectHandle = (uint64_t)(uintptr_t)phys_dev; |
| obj_name_info.objectType = VK_OBJECT_TYPE_PHYSICAL_DEVICE; |
| obj_name_info.pObjectName = "Physical Device AAAAAAAAA"; |
| ASSERT_EQ(VK_SUCCESS, SetDebugUtilsObjectNameEXT(dev.dev, &obj_name_info)); |
| |
| obj_name_info.objectHandle = (uint64_t)(uintptr_t)inst.inst; |
| obj_name_info.objectType = VK_OBJECT_TYPE_INSTANCE; |
| ASSERT_EQ(VK_SUCCESS, SetDebugUtilsObjectNameEXT(dev.dev, &obj_name_info)); |
| } |
| if (SetDebugUtilsObjectTagEXT) { |
| VkDebugUtilsObjectTagInfoEXT utils_object_tag{}; |
| utils_object_tag.objectHandle = (uint64_t)(uintptr_t)inst.inst; |
| utils_object_tag.objectType = VK_OBJECT_TYPE_INSTANCE; |
| ASSERT_EQ(VK_SUCCESS, SetDebugUtilsObjectTagEXT(dev.dev, &utils_object_tag)); |
| |
| utils_object_tag.objectHandle = (uint64_t)(uintptr_t)phys_dev; |
| utils_object_tag.objectType = VK_OBJECT_TYPE_PHYSICAL_DEVICE; |
| ASSERT_EQ(VK_SUCCESS, SetDebugUtilsObjectTagEXT(dev.dev, &utils_object_tag)); |
| |
| utils_object_tag.objectHandle = (uint64_t)surface; |
| utils_object_tag.objectType = VK_OBJECT_TYPE_SURFACE_KHR; |
| ASSERT_EQ(VK_SUCCESS, SetDebugUtilsObjectTagEXT(dev.dev, &utils_object_tag)); |
| } |
| 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) { |
| marker_object_tag.object = (uint64_t)(uintptr_t)swapchain; |
| marker_object_tag.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT; |
| ASSERT_EQ(VK_SUCCESS, DebugMarkerSetObjectTagEXT(dev.dev, &marker_object_tag)); |
| |
| marker_object_tag.object = (uint64_t)(uintptr_t)phys_dev; |
| marker_object_tag.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT; |
| ASSERT_EQ(VK_SUCCESS, DebugMarkerSetObjectTagEXT(dev.dev, &marker_object_tag)); |
| |
| marker_object_tag.object = (uint64_t)surface; |
| marker_object_tag.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT; |
| ASSERT_EQ(VK_SUCCESS, DebugMarkerSetObjectTagEXT(dev.dev, &marker_object_tag)); |
| |
| marker_object_tag.object = (uint64_t)(uintptr_t)inst.inst; |
| marker_object_tag.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT; |
| ASSERT_EQ(VK_SUCCESS, DebugMarkerSetObjectTagEXT(dev.dev, &marker_object_tag)); |
| } |
| if (DebugMarkerSetObjectNameEXT) { |
| marker_object_name.object = (uint64_t)(uintptr_t)swapchain; |
| marker_object_name.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT; |
| ASSERT_EQ(VK_SUCCESS, DebugMarkerSetObjectNameEXT(dev.dev, &marker_object_name)); |
| |
| marker_object_name.object = (uint64_t)(uintptr_t)phys_dev; |
| marker_object_name.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT; |
| ASSERT_EQ(VK_SUCCESS, DebugMarkerSetObjectNameEXT(dev.dev, &marker_object_name)); |
| |
| marker_object_name.object = (uint64_t)surface; |
| marker_object_name.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT; |
| ASSERT_EQ(VK_SUCCESS, DebugMarkerSetObjectNameEXT(dev.dev, &marker_object_name)); |
| |
| marker_object_name.object = (uint64_t)(uintptr_t)inst.inst; |
| marker_object_name.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT; |
| ASSERT_EQ(VK_SUCCESS, DebugMarkerSetObjectNameEXT(dev.dev, &marker_object_name)); |
| } |
| } |
| 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(GetProcAddr, DebugFuncsWithTerminator) { |
| FrameworkEnvironment env{}; |
| auto& driver = |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).setup_WSI().add_physical_device("physical_device_0"); |
| driver.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, false)); |
| ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, false, true, false)); |
| |
| // Use getInstanceProcAddr & vary enabling the debug extensions |
| ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, false, false)); |
| ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, true, false)); |
| |
| // Now set the hardware to support the extensions and run the situations again |
| driver.add_instance_extensions({"VK_EXT_debug_utils", "VK_EXT_debug_report"}); |
| driver.physical_devices.at(0).add_extensions({"VK_EXT_debug_marker"}); |
| |
| // Use getDeviceProcAddr & vary enabling the debug extensions |
| ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, false, false, true)); |
| ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, false, true, true)); |
| |
| // Use getInstanceProcAddr & vary enabling the debug extensions |
| ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, false, true)); |
| ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, true, true)); |
| } |
| |
| TEST(GetProcAddr, DebugFuncsWithTrampoline) { |
| FrameworkEnvironment env{}; |
| auto& driver = |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).setup_WSI().add_physical_device("physical_device_0"); |
| driver.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, false)); |
| ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, false, true, false)); |
| |
| // Use getInstanceProcAddr & vary enabling the debug extensions |
| ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, false, false)); |
| ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, true, false)); |
| |
| // Now add a layer that supports the extensions and run the situations again |
| env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} |
| .set_name("VK_LAYER_test_layer") |
| .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) |
| .set_disable_environment("DISABLE_ME") |
| .add_instance_extensions({{VK_EXT_DEBUG_REPORT_EXTENSION_NAME}, |
| {VK_EXT_DEBUG_UTILS_EXTENSION_NAME}}) |
| .add_device_extension({VK_EXT_DEBUG_MARKER_EXTENSION_NAME})), |
| "test_layer.json"); |
| |
| // // Use getDeviceProcAddr & vary enabling the debug extensions |
| ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, false, false, true)); |
| ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, false, true, true)); |
| |
| // Use getInstanceProcAddr & vary enabling the debug extensions |
| ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, false, true)); |
| ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, true, true)); |
| } |
| |
| TEST(GetProcAddr, DebugFuncsWithDebugExtsForceAdded) { |
| FrameworkEnvironment env{}; |
| auto& driver = |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).setup_WSI().add_physical_device("physical_device_0"); |
| driver.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, false)); |
| ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, false, true, false)); |
| |
| // Use getInstanceProcAddr & vary enabling the debug extensions |
| ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, false, false)); |
| ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, true, false)); |
| |
| // Now add a layer that supports the extensions and run the situations again |
| env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} |
| .set_name("VK_LAYER_test_layer") |
| .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) |
| .set_disable_environment("DISABLE_ME")), |
| "test_layer.json"); |
| env.get_test_layer() |
| .add_injected_instance_extensions({{VK_EXT_DEBUG_REPORT_EXTENSION_NAME}, {VK_EXT_DEBUG_UTILS_EXTENSION_NAME}}) |
| .add_injected_device_extension({VK_EXT_DEBUG_MARKER_EXTENSION_NAME}); |
| |
| // Use getDeviceProcAddr & vary enabling the debug extensions |
| ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, false, false, true)); |
| ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, false, true, true)); |
| |
| // Use getInstanceProcAddr & vary enabling the debug extensions |
| ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, false, true)); |
| ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, true, true)); |
| } |
| |
| TEST(DebugUtils, WrappingLayer) { |
| FrameworkEnvironment env{}; |
| env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)) |
| .set_min_icd_interface_version(5) |
| .add_physical_device(PhysicalDevice{}.add_extension(VK_EXT_DEBUG_MARKER_EXTENSION_NAME).finish()) |
| .add_instance_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); |
| |
| const char* wrap_objects_name = "VK_LAYER_LUNARG_wrap_objects"; |
| env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} |
| .set_name(wrap_objects_name) |
| .set_lib_path(TEST_LAYER_WRAP_OBJECTS) |
| .set_disable_environment("DISABLE_ME") |
| .add_instance_extension({VK_EXT_DEBUG_UTILS_EXTENSION_NAME})), |
| "wrap_objects_layer.json"); |
| |
| InstWrapper inst{env.vulkan_functions}; |
| inst.create_info.add_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); |
| inst.create_info.add_extension(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); |
| inst.create_info.add_layer(wrap_objects_name); |
| inst.CheckCreate(); |
| DebugUtilsWrapper log{inst}; |
| CreateDebugUtilsMessenger(log); |
| |
| auto phys_dev = inst.GetPhysDev(); |
| DeviceWrapper device{inst}; |
| device.create_info.add_extension(VK_EXT_DEBUG_MARKER_EXTENSION_NAME); |
| device.CheckCreate(phys_dev); |
| { |
| PFN_vkSetDebugUtilsObjectNameEXT SetDebugUtilsObjectNameEXT = inst.load("vkSetDebugUtilsObjectNameEXT"); |
| |
| VkDebugUtilsObjectNameInfoEXT info = {}; |
| info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; |
| info.objectType = VK_OBJECT_TYPE_DEVICE; |
| info.objectHandle = (uint64_t)device.dev; |
| info.pObjectName = "Test Name"; |
| ASSERT_EQ(VK_SUCCESS, SetDebugUtilsObjectNameEXT(device, &info)); |
| |
| info.objectType = VK_OBJECT_TYPE_PHYSICAL_DEVICE; |
| info.objectHandle = (uint64_t)phys_dev; |
| ASSERT_EQ(VK_SUCCESS, SetDebugUtilsObjectNameEXT(device, &info)); |
| |
| info.objectType = VK_OBJECT_TYPE_INSTANCE; |
| info.objectHandle = (uint64_t)inst.inst; |
| ASSERT_EQ(VK_SUCCESS, SetDebugUtilsObjectNameEXT(device, &info)); |
| } |
| { |
| PFN_vkSetDebugUtilsObjectTagEXT SetDebugUtilsObjectTagEXT = inst.load("vkSetDebugUtilsObjectTagEXT"); |
| |
| VkDebugUtilsObjectTagInfoEXT info = {}; |
| info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_TAG_INFO_EXT; |
| info.objectType = VK_OBJECT_TYPE_DEVICE; |
| info.objectHandle = (uint64_t)device.dev; |
| info.pTag = "Test Name"; |
| ASSERT_EQ(VK_SUCCESS, SetDebugUtilsObjectTagEXT(device, &info)); |
| |
| info.objectType = VK_OBJECT_TYPE_PHYSICAL_DEVICE; |
| info.objectHandle = (uint64_t)phys_dev; |
| ASSERT_EQ(VK_SUCCESS, SetDebugUtilsObjectTagEXT(device, &info)); |
| |
| info.objectType = VK_OBJECT_TYPE_INSTANCE; |
| info.objectHandle = (uint64_t)inst.inst; |
| ASSERT_EQ(VK_SUCCESS, SetDebugUtilsObjectTagEXT(device, &info)); |
| } |
| // Debug marker |
| { |
| PFN_vkDebugMarkerSetObjectNameEXT DebugMarkerSetObjectNameEXT = inst.load("vkDebugMarkerSetObjectNameEXT"); |
| |
| VkDebugMarkerObjectNameInfoEXT info = {}; |
| info.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT; |
| info.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT; |
| info.object = (uint64_t)device.dev; |
| info.pObjectName = "Test Name"; |
| ASSERT_EQ(VK_SUCCESS, DebugMarkerSetObjectNameEXT(device, &info)); |
| |
| info.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT; |
| info.object = (uint64_t)phys_dev; |
| ASSERT_EQ(VK_SUCCESS, DebugMarkerSetObjectNameEXT(device, &info)); |
| |
| info.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT; |
| info.object = (uint64_t)inst.inst; |
| ASSERT_EQ(VK_SUCCESS, DebugMarkerSetObjectNameEXT(device, &info)); |
| } |
| { |
| PFN_vkDebugMarkerSetObjectTagEXT DebugMarkerSetObjectTagEXT = inst.load("vkDebugMarkerSetObjectTagEXT"); |
| |
| VkDebugMarkerObjectTagInfoEXT info = {}; |
| info.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_TAG_INFO_EXT; |
| info.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT; |
| info.object = (uint64_t)device.dev; |
| info.pTag = "Test Name"; |
| ASSERT_EQ(VK_SUCCESS, DebugMarkerSetObjectTagEXT(device, &info)); |
| |
| info.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT; |
| info.object = (uint64_t)phys_dev; |
| ASSERT_EQ(VK_SUCCESS, DebugMarkerSetObjectTagEXT(device, &info)); |
| |
| info.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT; |
| info.object = (uint64_t)inst.inst; |
| ASSERT_EQ(VK_SUCCESS, DebugMarkerSetObjectTagEXT(device, &info)); |
| } |
| } |