renderer_vulkan: Add suport for debug report callback
This commit is contained in:
parent
0fe44071f8
commit
72e7f5b4dd
|
@ -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