renderer_vulkan: Add suport for debug report callback
This commit is contained in:
		| @@ -12,6 +12,7 @@ | |||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
|  |  | ||||||
| #include "common/logging/log.h" | #include "common/logging/log.h" | ||||||
|  | #include "common/polyfill_ranges.h" | ||||||
| #include "common/scope_exit.h" | #include "common/scope_exit.h" | ||||||
| #include "common/settings.h" | #include "common/settings.h" | ||||||
| #include "common/telemetry.h" | #include "common/telemetry.h" | ||||||
| @@ -65,6 +66,21 @@ std::string BuildCommaSeparatedExtensions( | |||||||
|     return fmt::format("{}", fmt::join(available_extensions, ",")); |     return fmt::format("{}", fmt::join(available_extensions, ",")); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | DebugCallback MakeDebugCallback(const vk::Instance& instance, const vk::InstanceDispatch& dld) { | ||||||
|  |     if (!Settings::values.renderer_debug) { | ||||||
|  |         return DebugCallback{}; | ||||||
|  |     } | ||||||
|  |     const std::optional properties = vk::EnumerateInstanceExtensionProperties(dld); | ||||||
|  |     const auto it = std::ranges::find_if(*properties, [](const auto& prop) { | ||||||
|  |         return std::strcmp(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, prop.extensionName) == 0; | ||||||
|  |     }); | ||||||
|  |     if (it != properties->end()) { | ||||||
|  |         return CreateDebugUtilsCallback(instance); | ||||||
|  |     } else { | ||||||
|  |         return CreateDebugReportCallback(instance); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| } // Anonymous namespace | } // Anonymous namespace | ||||||
|  |  | ||||||
| Device CreateDevice(const vk::Instance& instance, const vk::InstanceDispatch& dld, | Device CreateDevice(const vk::Instance& instance, const vk::InstanceDispatch& dld, | ||||||
| @@ -87,7 +103,7 @@ RendererVulkan::RendererVulkan(Core::TelemetrySession& telemetry_session_, | |||||||
|       cpu_memory(cpu_memory_), gpu(gpu_), library(OpenLibrary(context.get())), |       cpu_memory(cpu_memory_), gpu(gpu_), library(OpenLibrary(context.get())), | ||||||
|       instance(CreateInstance(*library, dld, VK_API_VERSION_1_1, render_window.GetWindowInfo().type, |       instance(CreateInstance(*library, dld, VK_API_VERSION_1_1, render_window.GetWindowInfo().type, | ||||||
|                               Settings::values.renderer_debug.GetValue())), |                               Settings::values.renderer_debug.GetValue())), | ||||||
|       debug_callback(Settings::values.renderer_debug ? CreateDebugCallback(instance) : nullptr), |       debug_callback(MakeDebugCallback(instance, dld)), | ||||||
|       surface(CreateSurface(instance, render_window.GetWindowInfo())), |       surface(CreateSurface(instance, render_window.GetWindowInfo())), | ||||||
|       device(CreateDevice(instance, dld, *surface)), memory_allocator(device), state_tracker(), |       device(CreateDevice(instance, dld, *surface)), memory_allocator(device), state_tracker(), | ||||||
|       scheduler(device, state_tracker), |       scheduler(device, state_tracker), | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ | |||||||
|  |  | ||||||
| #include <memory> | #include <memory> | ||||||
| #include <string> | #include <string> | ||||||
|  | #include <variant> | ||||||
|  |  | ||||||
| #include "common/dynamic_library.h" | #include "common/dynamic_library.h" | ||||||
| #include "video_core/renderer_base.h" | #include "video_core/renderer_base.h" | ||||||
| @@ -33,6 +34,8 @@ class GPU; | |||||||
|  |  | ||||||
| namespace Vulkan { | namespace Vulkan { | ||||||
|  |  | ||||||
|  | using DebugCallback = std::variant<vk::DebugUtilsMessenger, vk::DebugReportCallback>; | ||||||
|  |  | ||||||
| Device CreateDevice(const vk::Instance& instance, const vk::InstanceDispatch& dld, | Device CreateDevice(const vk::Instance& instance, const vk::InstanceDispatch& dld, | ||||||
|                     VkSurfaceKHR surface); |                     VkSurfaceKHR surface); | ||||||
|  |  | ||||||
| @@ -71,7 +74,7 @@ private: | |||||||
|     vk::InstanceDispatch dld; |     vk::InstanceDispatch dld; | ||||||
|  |  | ||||||
|     vk::Instance instance; |     vk::Instance instance; | ||||||
|     vk::DebugUtilsMessenger debug_callback; |     DebugCallback debug_callback; | ||||||
|     vk::SurfaceKHR surface; |     vk::SurfaceKHR surface; | ||||||
|  |  | ||||||
|     ScreenInfo screen_info; |     ScreenInfo screen_info; | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
|  |  | ||||||
| namespace Vulkan { | namespace Vulkan { | ||||||
| namespace { | namespace { | ||||||
| VkBool32 Callback(VkDebugUtilsMessageSeverityFlagBitsEXT severity, | VkBool32 DebugUtilCallback(VkDebugUtilsMessageSeverityFlagBitsEXT severity, | ||||||
|                            VkDebugUtilsMessageTypeFlagsEXT type, |                            VkDebugUtilsMessageTypeFlagsEXT type, | ||||||
|                            const VkDebugUtilsMessengerCallbackDataEXT* data, |                            const VkDebugUtilsMessengerCallbackDataEXT* data, | ||||||
|                            [[maybe_unused]] void* user_data) { |                            [[maybe_unused]] void* user_data) { | ||||||
| @@ -62,9 +62,26 @@ VkBool32 Callback(VkDebugUtilsMessageSeverityFlagBitsEXT severity, | |||||||
|     } |     } | ||||||
|     return VK_FALSE; |     return VK_FALSE; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | VkBool32 DebugReportCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, | ||||||
|  |                              uint64_t object, size_t location, int32_t messageCode, | ||||||
|  |                              const char* pLayerPrefix, const char* pMessage, void* pUserData) { | ||||||
|  |     const VkDebugReportFlagBitsEXT severity = static_cast<VkDebugReportFlagBitsEXT>(flags); | ||||||
|  |     const std::string_view message{pMessage}; | ||||||
|  |     if (severity & VK_DEBUG_REPORT_ERROR_BIT_EXT) { | ||||||
|  |         LOG_CRITICAL(Render_Vulkan, "{}", message); | ||||||
|  |     } else if (severity & VK_DEBUG_REPORT_WARNING_BIT_EXT) { | ||||||
|  |         LOG_WARNING(Render_Vulkan, "{}", message); | ||||||
|  |     } else if (severity & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) { | ||||||
|  |         LOG_INFO(Render_Vulkan, "{}", message); | ||||||
|  |     } else if (severity & VK_DEBUG_REPORT_DEBUG_BIT_EXT) { | ||||||
|  |         LOG_DEBUG(Render_Vulkan, "{}", message); | ||||||
|  |     } | ||||||
|  |     return VK_FALSE; | ||||||
|  | } | ||||||
| } // Anonymous namespace | } // Anonymous namespace | ||||||
|  |  | ||||||
| vk::DebugUtilsMessenger CreateDebugCallback(const vk::Instance& instance) { | vk::DebugUtilsMessenger CreateDebugUtilsCallback(const vk::Instance& instance) { | ||||||
|     return instance.CreateDebugUtilsMessenger(VkDebugUtilsMessengerCreateInfoEXT{ |     return instance.CreateDebugUtilsMessenger(VkDebugUtilsMessengerCreateInfoEXT{ | ||||||
|         .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, |         .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, | ||||||
|         .pNext = nullptr, |         .pNext = nullptr, | ||||||
| @@ -76,7 +93,18 @@ vk::DebugUtilsMessenger CreateDebugCallback(const vk::Instance& instance) { | |||||||
|         .messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | |         .messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | | ||||||
|                        VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | |                        VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | | ||||||
|                        VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, |                        VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, | ||||||
|         .pfnUserCallback = Callback, |         .pfnUserCallback = DebugUtilCallback, | ||||||
|  |         .pUserData = nullptr, | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | vk::DebugReportCallback CreateDebugReportCallback(const vk::Instance& instance) { | ||||||
|  |     return instance.CreateDebugReportCallback({ | ||||||
|  |         .sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT, | ||||||
|  |         .pNext = nullptr, | ||||||
|  |         .flags = VK_DEBUG_REPORT_DEBUG_BIT_EXT | VK_DEBUG_REPORT_INFORMATION_BIT_EXT | | ||||||
|  |                  VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT, | ||||||
|  |         .pfnCallback = DebugReportCallback, | ||||||
|         .pUserData = nullptr, |         .pUserData = nullptr, | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -7,6 +7,8 @@ | |||||||
|  |  | ||||||
| namespace Vulkan { | namespace Vulkan { | ||||||
|  |  | ||||||
| vk::DebugUtilsMessenger CreateDebugCallback(const vk::Instance& instance); | vk::DebugUtilsMessenger CreateDebugUtilsCallback(const vk::Instance& instance); | ||||||
|  |  | ||||||
|  | vk::DebugReportCallback CreateDebugReportCallback(const vk::Instance& instance); | ||||||
|  |  | ||||||
| } // namespace Vulkan | } // namespace Vulkan | ||||||
|   | |||||||
| @@ -349,7 +349,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR | |||||||
|     const bool is_s8gen2 = device_id == 0x43050a01; |     const bool is_s8gen2 = device_id == 0x43050a01; | ||||||
|     const bool is_arm = driver_id == VK_DRIVER_ID_ARM_PROPRIETARY; |     const bool is_arm = driver_id == VK_DRIVER_ID_ARM_PROPRIETARY; | ||||||
|  |  | ||||||
|     if ((is_mvk || is_qualcomm || is_turnip) && !is_suitable) { |     if ((is_mvk || is_qualcomm || is_turnip || is_arm) && !is_suitable) { | ||||||
|         LOG_WARNING(Render_Vulkan, "Unsuitable driver, continuing anyway"); |         LOG_WARNING(Render_Vulkan, "Unsuitable driver, continuing anyway"); | ||||||
|     } else if (!is_suitable) { |     } else if (!is_suitable) { | ||||||
|         throw vk::Exception(VK_ERROR_INCOMPATIBLE_DRIVER); |         throw vk::Exception(VK_ERROR_INCOMPATIBLE_DRIVER); | ||||||
|   | |||||||
| @@ -31,10 +31,34 @@ | |||||||
|  |  | ||||||
| namespace Vulkan { | namespace Vulkan { | ||||||
| namespace { | namespace { | ||||||
|  |  | ||||||
|  | [[nodiscard]] bool AreExtensionsSupported(const vk::InstanceDispatch& dld, | ||||||
|  |                                           std::span<const char* const> extensions) { | ||||||
|  |     const std::optional properties = vk::EnumerateInstanceExtensionProperties(dld); | ||||||
|  |     if (!properties) { | ||||||
|  |         LOG_ERROR(Render_Vulkan, "Failed to query extension properties"); | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |     for (const char* extension : extensions) { | ||||||
|  |         const auto it = std::ranges::find_if(*properties, [extension](const auto& prop) { | ||||||
|  |             return std::strcmp(extension, prop.extensionName) == 0; | ||||||
|  |         }); | ||||||
|  |         if (it == properties->end()) { | ||||||
|  |             LOG_ERROR(Render_Vulkan, "Required instance extension {} is not available", extension); | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return true; | ||||||
|  | } | ||||||
|  |  | ||||||
| [[nodiscard]] std::vector<const char*> RequiredExtensions( | [[nodiscard]] std::vector<const char*> RequiredExtensions( | ||||||
|     Core::Frontend::WindowSystemType window_type, bool enable_validation) { |     const vk::InstanceDispatch& dld, Core::Frontend::WindowSystemType window_type, | ||||||
|  |     bool enable_validation) { | ||||||
|     std::vector<const char*> extensions; |     std::vector<const char*> extensions; | ||||||
|     extensions.reserve(6); |     extensions.reserve(6); | ||||||
|  | #ifdef __APPLE__ | ||||||
|  |     extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME); | ||||||
|  | #endif | ||||||
|     switch (window_type) { |     switch (window_type) { | ||||||
|     case Core::Frontend::WindowSystemType::Headless: |     case Core::Frontend::WindowSystemType::Headless: | ||||||
|         break; |         break; | ||||||
| @@ -66,35 +90,14 @@ namespace { | |||||||
|         extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME); |         extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME); | ||||||
|     } |     } | ||||||
|     if (enable_validation) { |     if (enable_validation) { | ||||||
|         extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); |         const bool debug_utils = | ||||||
|  |             AreExtensionsSupported(dld, std::array{VK_EXT_DEBUG_UTILS_EXTENSION_NAME}); | ||||||
|  |         extensions.push_back(debug_utils ? VK_EXT_DEBUG_UTILS_EXTENSION_NAME | ||||||
|  |                                          : VK_EXT_DEBUG_REPORT_EXTENSION_NAME); | ||||||
|     } |     } | ||||||
|     extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |  | ||||||
|  |  | ||||||
| #ifdef __APPLE__ |  | ||||||
|     extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME); |  | ||||||
| #endif |  | ||||||
|     return extensions; |     return extensions; | ||||||
| } | } | ||||||
|  |  | ||||||
| [[nodiscard]] bool AreExtensionsSupported(const vk::InstanceDispatch& dld, |  | ||||||
|                                           std::span<const char* const> extensions) { |  | ||||||
|     const std::optional properties = vk::EnumerateInstanceExtensionProperties(dld); |  | ||||||
|     if (!properties) { |  | ||||||
|         LOG_ERROR(Render_Vulkan, "Failed to query extension properties"); |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
|     for (const char* extension : extensions) { |  | ||||||
|         const auto it = std::ranges::find_if(*properties, [extension](const auto& prop) { |  | ||||||
|             return std::strcmp(extension, prop.extensionName) == 0; |  | ||||||
|         }); |  | ||||||
|         if (it == properties->end()) { |  | ||||||
|             LOG_ERROR(Render_Vulkan, "Required instance extension {} is not available", extension); |  | ||||||
|             return false; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     return true; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| [[nodiscard]] std::vector<const char*> Layers(bool enable_validation) { | [[nodiscard]] std::vector<const char*> Layers(bool enable_validation) { | ||||||
|     std::vector<const char*> layers; |     std::vector<const char*> layers; | ||||||
|     if (enable_validation) { |     if (enable_validation) { | ||||||
| @@ -138,7 +141,8 @@ vk::Instance CreateInstance(const Common::DynamicLibrary& library, vk::InstanceD | |||||||
|         LOG_ERROR(Render_Vulkan, "Failed to load Vulkan function pointers"); |         LOG_ERROR(Render_Vulkan, "Failed to load Vulkan function pointers"); | ||||||
|         throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED); |         throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED); | ||||||
|     } |     } | ||||||
|     const std::vector<const char*> extensions = RequiredExtensions(window_type, enable_validation); |     const std::vector<const char*> extensions = | ||||||
|  |         RequiredExtensions(dld, window_type, enable_validation); | ||||||
|     if (!AreExtensionsSupported(dld, extensions)) { |     if (!AreExtensionsSupported(dld, extensions)) { | ||||||
|         throw vk::Exception(VK_ERROR_EXTENSION_NOT_PRESENT); |         throw vk::Exception(VK_ERROR_EXTENSION_NOT_PRESENT); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -259,7 +259,9 @@ bool Load(VkInstance instance, InstanceDispatch& dld) noexcept { | |||||||
|     // These functions may fail to load depending on the enabled extensions. |     // These functions may fail to load depending on the enabled extensions. | ||||||
|     // Don't return a failure on these. |     // Don't return a failure on these. | ||||||
|     X(vkCreateDebugUtilsMessengerEXT); |     X(vkCreateDebugUtilsMessengerEXT); | ||||||
|  |     X(vkCreateDebugReportCallbackEXT); | ||||||
|     X(vkDestroyDebugUtilsMessengerEXT); |     X(vkDestroyDebugUtilsMessengerEXT); | ||||||
|  |     X(vkDestroyDebugReportCallbackEXT); | ||||||
|     X(vkDestroySurfaceKHR); |     X(vkDestroySurfaceKHR); | ||||||
|     X(vkGetPhysicalDeviceFeatures2); |     X(vkGetPhysicalDeviceFeatures2); | ||||||
|     X(vkGetPhysicalDeviceProperties2); |     X(vkGetPhysicalDeviceProperties2); | ||||||
| @@ -481,6 +483,11 @@ void Destroy(VkInstance instance, VkDebugUtilsMessengerEXT handle, | |||||||
|     dld.vkDestroyDebugUtilsMessengerEXT(instance, handle, nullptr); |     dld.vkDestroyDebugUtilsMessengerEXT(instance, handle, nullptr); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void Destroy(VkInstance instance, VkDebugReportCallbackEXT handle, | ||||||
|  |              const InstanceDispatch& dld) noexcept { | ||||||
|  |     dld.vkDestroyDebugReportCallbackEXT(instance, handle, nullptr); | ||||||
|  | } | ||||||
|  |  | ||||||
| void Destroy(VkInstance instance, VkSurfaceKHR handle, const InstanceDispatch& dld) noexcept { | void Destroy(VkInstance instance, VkSurfaceKHR handle, const InstanceDispatch& dld) noexcept { | ||||||
|     dld.vkDestroySurfaceKHR(instance, handle, nullptr); |     dld.vkDestroySurfaceKHR(instance, handle, nullptr); | ||||||
| } | } | ||||||
| @@ -549,6 +556,13 @@ DebugUtilsMessenger Instance::CreateDebugUtilsMessenger( | |||||||
|     return DebugUtilsMessenger(object, handle, *dld); |     return DebugUtilsMessenger(object, handle, *dld); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | DebugReportCallback Instance::CreateDebugReportCallback( | ||||||
|  |     const VkDebugReportCallbackCreateInfoEXT& create_info) const { | ||||||
|  |     VkDebugReportCallbackEXT object; | ||||||
|  |     Check(dld->vkCreateDebugReportCallbackEXT(handle, &create_info, nullptr, &object)); | ||||||
|  |     return DebugReportCallback(object, handle, *dld); | ||||||
|  | } | ||||||
|  |  | ||||||
| void Image::SetObjectNameEXT(const char* name) const { | void Image::SetObjectNameEXT(const char* name) const { | ||||||
|     SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_IMAGE, name); |     SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_IMAGE, name); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -164,8 +164,10 @@ struct InstanceDispatch { | |||||||
|     PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties{}; |     PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties{}; | ||||||
|  |  | ||||||
|     PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT{}; |     PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT{}; | ||||||
|  |     PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT{}; | ||||||
|     PFN_vkCreateDevice vkCreateDevice{}; |     PFN_vkCreateDevice vkCreateDevice{}; | ||||||
|     PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT{}; |     PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT{}; | ||||||
|  |     PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT{}; | ||||||
|     PFN_vkDestroyDevice vkDestroyDevice{}; |     PFN_vkDestroyDevice vkDestroyDevice{}; | ||||||
|     PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR{}; |     PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR{}; | ||||||
|     PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties{}; |     PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties{}; | ||||||
| @@ -366,6 +368,7 @@ void Destroy(VkDevice, VkSwapchainKHR, const DeviceDispatch&) noexcept; | |||||||
| void Destroy(VkDevice, VkSemaphore, const DeviceDispatch&) noexcept; | void Destroy(VkDevice, VkSemaphore, const DeviceDispatch&) noexcept; | ||||||
| void Destroy(VkDevice, VkShaderModule, const DeviceDispatch&) noexcept; | void Destroy(VkDevice, VkShaderModule, const DeviceDispatch&) noexcept; | ||||||
| void Destroy(VkInstance, VkDebugUtilsMessengerEXT, const InstanceDispatch&) noexcept; | void Destroy(VkInstance, VkDebugUtilsMessengerEXT, const InstanceDispatch&) noexcept; | ||||||
|  | void Destroy(VkInstance, VkDebugReportCallbackEXT, const InstanceDispatch&) noexcept; | ||||||
| void Destroy(VkInstance, VkSurfaceKHR, const InstanceDispatch&) noexcept; | void Destroy(VkInstance, VkSurfaceKHR, const InstanceDispatch&) noexcept; | ||||||
|  |  | ||||||
| VkResult Free(VkDevice, VkDescriptorPool, Span<VkDescriptorSet>, const DeviceDispatch&) noexcept; | VkResult Free(VkDevice, VkDescriptorPool, Span<VkDescriptorSet>, const DeviceDispatch&) noexcept; | ||||||
| @@ -581,6 +584,7 @@ private: | |||||||
| }; | }; | ||||||
|  |  | ||||||
| using DebugUtilsMessenger = Handle<VkDebugUtilsMessengerEXT, VkInstance, InstanceDispatch>; | using DebugUtilsMessenger = Handle<VkDebugUtilsMessengerEXT, VkInstance, InstanceDispatch>; | ||||||
|  | using DebugReportCallback = Handle<VkDebugReportCallbackEXT, VkInstance, InstanceDispatch>; | ||||||
| using DescriptorSetLayout = Handle<VkDescriptorSetLayout, VkDevice, DeviceDispatch>; | using DescriptorSetLayout = Handle<VkDescriptorSetLayout, VkDevice, DeviceDispatch>; | ||||||
| using DescriptorUpdateTemplate = Handle<VkDescriptorUpdateTemplate, VkDevice, DeviceDispatch>; | using DescriptorUpdateTemplate = Handle<VkDescriptorUpdateTemplate, VkDevice, DeviceDispatch>; | ||||||
| using Pipeline = Handle<VkPipeline, VkDevice, DeviceDispatch>; | using Pipeline = Handle<VkPipeline, VkDevice, DeviceDispatch>; | ||||||
| @@ -613,6 +617,11 @@ public: | |||||||
|     DebugUtilsMessenger CreateDebugUtilsMessenger( |     DebugUtilsMessenger CreateDebugUtilsMessenger( | ||||||
|         const VkDebugUtilsMessengerCreateInfoEXT& create_info) const; |         const VkDebugUtilsMessengerCreateInfoEXT& create_info) const; | ||||||
|  |  | ||||||
|  |     /// Creates a debug report callback. | ||||||
|  |     /// @throw Exception on creation failure. | ||||||
|  |     DebugReportCallback CreateDebugReportCallback( | ||||||
|  |         const VkDebugReportCallbackCreateInfoEXT& create_info) const; | ||||||
|  |  | ||||||
|     /// Returns dispatch table. |     /// Returns dispatch table. | ||||||
|     const InstanceDispatch& Dispatch() const noexcept { |     const InstanceDispatch& Dispatch() const noexcept { | ||||||
|         return *dld; |         return *dld; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user