renderer_vulkan: Forward validation errors to logfile
This commit is contained in:
@@ -15,6 +15,56 @@ namespace Vulkan {
|
||||
|
||||
vk::DynamicLoader Instance::dl;
|
||||
|
||||
inline std::string_view GetType(vk::DebugUtilsMessageTypeFlagBitsEXT type) {
|
||||
switch (type) {
|
||||
case vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral:
|
||||
return "General";
|
||||
case vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation:
|
||||
return "Validation";
|
||||
case vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance:
|
||||
return "Performance";
|
||||
case vk::DebugUtilsMessageTypeFlagBitsEXT::eDeviceAddressBinding:
|
||||
return "DeviceAddressBinding";
|
||||
default:
|
||||
return "";
|
||||
};
|
||||
}
|
||||
|
||||
static VKAPI_ATTR VkBool32 VKAPI_CALL DebugHandler(
|
||||
VkDebugUtilsMessageSeverityFlagBitsEXT severity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT type,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT* callback_data,
|
||||
void* user_data) {
|
||||
|
||||
switch (callback_data->messageIdNumber) {
|
||||
case 0x609a13b: // Vertex attribute at location not consumed by shader
|
||||
return VK_FALSE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Log::Level level{};
|
||||
switch (severity) {
|
||||
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT:
|
||||
level = Log::Level::Error;
|
||||
break;
|
||||
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT:
|
||||
level = Log::Level::Info;
|
||||
break;
|
||||
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT:
|
||||
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT:
|
||||
level = Log::Level::Debug;
|
||||
break;
|
||||
default:
|
||||
level = Log::Level::Info;
|
||||
}
|
||||
|
||||
LOG_GENERIC(Log::Class::Render_Vulkan, level, "{}: {}",
|
||||
callback_data->pMessageIdName, callback_data->pMessage);
|
||||
|
||||
return VK_FALSE;
|
||||
}
|
||||
|
||||
vk::Format ToVkFormat(VideoCore::PixelFormat format) {
|
||||
switch (format) {
|
||||
case VideoCore::PixelFormat::RGBA8:
|
||||
@@ -42,6 +92,20 @@ vk::Format ToVkFormat(VideoCore::PixelFormat format) {
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] vk::DebugUtilsMessengerCreateInfoEXT MakeDebugUtilsMessengerInfo() {
|
||||
return {
|
||||
.messageSeverity = vk::DebugUtilsMessageSeverityFlagBitsEXT::eInfo |
|
||||
vk::DebugUtilsMessageSeverityFlagBitsEXT::eError |
|
||||
vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning |
|
||||
vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose,
|
||||
.messageType = vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral |
|
||||
vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation |
|
||||
vk::DebugUtilsMessageTypeFlagBitsEXT::eDeviceAddressBinding |
|
||||
vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance,
|
||||
.pfnUserCallback = DebugHandler
|
||||
};
|
||||
}
|
||||
|
||||
std::vector<std::string> GetSupportedExtensions(vk::PhysicalDevice physical) {
|
||||
const std::vector extensions = physical.enumerateDeviceExtensionProperties();
|
||||
std::vector<std::string> supported_extensions;
|
||||
@@ -52,7 +116,9 @@ std::vector<std::string> GetSupportedExtensions(vk::PhysicalDevice physical) {
|
||||
return supported_extensions;
|
||||
}
|
||||
|
||||
Instance::Instance(bool validation, bool dump_command_buffers) {
|
||||
Instance::Instance(bool validation, bool dump_command_buffers) :
|
||||
enable_validation{validation},
|
||||
dump_command_buffers{dump_command_buffers}{
|
||||
// Fetch instance independant function pointers
|
||||
auto vkGetInstanceProcAddr =
|
||||
dl.getProcAddress<PFN_vkGetInstanceProcAddr>("vkGetInstanceProcAddr");
|
||||
@@ -73,22 +139,27 @@ Instance::Instance(bool validation, bool dump_command_buffers) {
|
||||
u32 layer_count = 0;
|
||||
std::array<const char*, 2> layers;
|
||||
|
||||
if (validation) {
|
||||
if (enable_validation) {
|
||||
layers[layer_count++] = "VK_LAYER_KHRONOS_validation";
|
||||
}
|
||||
if (dump_command_buffers) {
|
||||
layers[layer_count++] = "VK_LAYER_LUNARG_api_dump";
|
||||
}
|
||||
|
||||
const vk::InstanceCreateInfo instance_info = {.flags = flags,
|
||||
.pApplicationInfo = &application_info,
|
||||
.enabledLayerCount = layer_count,
|
||||
.ppEnabledLayerNames = layers.data(),
|
||||
.enabledExtensionCount =
|
||||
static_cast<u32>(extensions.size()),
|
||||
.ppEnabledExtensionNames = extensions.data()};
|
||||
const vk::StructureChain instance_chain = {
|
||||
vk::InstanceCreateInfo{
|
||||
.flags = flags,
|
||||
.pApplicationInfo = &application_info,
|
||||
.enabledLayerCount = layer_count,
|
||||
.ppEnabledLayerNames = layers.data(),
|
||||
.enabledExtensionCount =
|
||||
static_cast<u32>(extensions.size()),
|
||||
.ppEnabledExtensionNames = extensions.data()
|
||||
},
|
||||
MakeDebugUtilsMessengerInfo()
|
||||
};
|
||||
|
||||
instance = vk::createInstance(instance_info);
|
||||
instance = vk::createInstance(instance_chain.get());
|
||||
|
||||
// Load required function pointers for querying the physical device
|
||||
VULKAN_HPP_DEFAULT_DISPATCHER.vkEnumeratePhysicalDevices = PFN_vkEnumeratePhysicalDevices(
|
||||
@@ -101,7 +172,9 @@ Instance::Instance(bool validation, bool dump_command_buffers) {
|
||||
physical_devices = instance.enumeratePhysicalDevices();
|
||||
}
|
||||
|
||||
Instance::Instance(Frontend::EmuWindow& window, u32 physical_device_index) {
|
||||
Instance::Instance(Frontend::EmuWindow& window, u32 physical_device_index) :
|
||||
enable_validation{Settings::values.renderer_debug},
|
||||
dump_command_buffers{Settings::values.dump_command_buffers} {
|
||||
auto window_info = window.GetWindowInfo();
|
||||
|
||||
// Fetch instance independant function pointers
|
||||
@@ -131,23 +204,28 @@ Instance::Instance(Frontend::EmuWindow& window, u32 physical_device_index) {
|
||||
u32 layer_count = 0;
|
||||
std::array<const char*, 2> layers;
|
||||
|
||||
if (Settings::values.renderer_debug) {
|
||||
if (enable_validation) {
|
||||
layers[layer_count++] = "VK_LAYER_KHRONOS_validation";
|
||||
}
|
||||
if (Settings::values.dump_command_buffers) {
|
||||
if (dump_command_buffers) {
|
||||
layers[layer_count++] = "VK_LAYER_LUNARG_api_dump";
|
||||
}
|
||||
|
||||
const vk::InstanceCreateInfo instance_info = {.flags = flags,
|
||||
.pApplicationInfo = &application_info,
|
||||
.enabledLayerCount = layer_count,
|
||||
.ppEnabledLayerNames = layers.data(),
|
||||
.enabledExtensionCount =
|
||||
static_cast<u32>(extensions.size()),
|
||||
.ppEnabledExtensionNames = extensions.data()};
|
||||
const vk::StructureChain instance_chain = {
|
||||
vk::InstanceCreateInfo{
|
||||
.flags = flags,
|
||||
.pApplicationInfo = &application_info,
|
||||
.enabledLayerCount = layer_count,
|
||||
.ppEnabledLayerNames = layers.data(),
|
||||
.enabledExtensionCount =
|
||||
static_cast<u32>(extensions.size()),
|
||||
.ppEnabledExtensionNames = extensions.data()
|
||||
},
|
||||
MakeDebugUtilsMessengerInfo()
|
||||
};
|
||||
|
||||
try {
|
||||
instance = vk::createInstance(instance_info);
|
||||
instance = vk::createInstance(instance_chain.get());
|
||||
} catch (vk::LayerNotPresentError& err) {
|
||||
LOG_CRITICAL(Render_Vulkan, "Validation requested but layer is not available {}", err.what());
|
||||
UNREACHABLE();
|
||||
@@ -155,6 +233,11 @@ Instance::Instance(Frontend::EmuWindow& window, u32 physical_device_index) {
|
||||
|
||||
surface = CreateSurface(instance, window);
|
||||
|
||||
// Calling this after CreateSurface to ensure the function has been loaded
|
||||
if (enable_validation) {
|
||||
CreateDebugMessenger();
|
||||
}
|
||||
|
||||
// Pick physical device
|
||||
physical_devices = instance.enumeratePhysicalDevices();
|
||||
if (const u16 physical_device_count = static_cast<u16>(physical_devices.size());
|
||||
@@ -180,6 +263,10 @@ Instance::~Instance() {
|
||||
vmaDestroyAllocator(allocator);
|
||||
device.destroy();
|
||||
instance.destroySurfaceKHR(surface);
|
||||
|
||||
if (enable_validation) {
|
||||
instance.destroyDebugUtilsMessengerEXT(debug_messenger);
|
||||
}
|
||||
}
|
||||
|
||||
instance.destroy();
|
||||
@@ -422,6 +509,22 @@ void Instance::CreateAllocator() {
|
||||
}
|
||||
}
|
||||
|
||||
void Instance::CreateDebugMessenger() {
|
||||
const vk::DebugUtilsMessengerCreateInfoEXT debug_info = {
|
||||
.messageSeverity = vk::DebugUtilsMessageSeverityFlagBitsEXT::eInfo |
|
||||
vk::DebugUtilsMessageSeverityFlagBitsEXT::eError |
|
||||
vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning |
|
||||
vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose,
|
||||
.messageType = vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral |
|
||||
vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation |
|
||||
vk::DebugUtilsMessageTypeFlagBitsEXT::eDeviceAddressBinding |
|
||||
vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance,
|
||||
.pfnUserCallback = DebugHandler
|
||||
};
|
||||
|
||||
debug_messenger = instance.createDebugUtilsMessengerEXT(debug_info);
|
||||
}
|
||||
|
||||
void Instance::CollectTelemetryParameters() {
|
||||
const vk::StructureChain property_chain =
|
||||
physical_device.getProperties2<vk::PhysicalDeviceProperties2,
|
||||
|
@@ -173,6 +173,9 @@ private:
|
||||
/// Creates the VMA allocator handle
|
||||
void CreateAllocator();
|
||||
|
||||
/// Creates the debug messenger
|
||||
void CreateDebugMessenger();
|
||||
|
||||
/// Collects telemetry information from the device.
|
||||
void CollectTelemetryParameters();
|
||||
|
||||
@@ -191,6 +194,7 @@ private:
|
||||
vk::PhysicalDeviceProperties properties;
|
||||
vk::PhysicalDeviceFeatures features;
|
||||
vk::DriverIdKHR driver_id;
|
||||
vk::DebugUtilsMessengerEXT debug_messenger;
|
||||
std::string vendor_name;
|
||||
VmaAllocator allocator;
|
||||
vk::Queue present_queue;
|
||||
@@ -198,12 +202,14 @@ private:
|
||||
std::vector<vk::PhysicalDevice> physical_devices;
|
||||
std::array<FormatTraits, VideoCore::PIXEL_FORMAT_COUNT> format_table;
|
||||
std::vector<std::string> available_extensions;
|
||||
u32 present_queue_family_index = 0;
|
||||
u32 graphics_queue_family_index = 0;
|
||||
bool timeline_semaphores = false;
|
||||
bool extended_dynamic_state = false;
|
||||
bool push_descriptors = false;
|
||||
bool custom_border_color = false;
|
||||
u32 present_queue_family_index{0};
|
||||
u32 graphics_queue_family_index{0};
|
||||
bool timeline_semaphores{false};
|
||||
bool extended_dynamic_state{false};
|
||||
bool push_descriptors{false};
|
||||
bool custom_border_color{false};
|
||||
bool enable_validation{false};
|
||||
bool dump_command_buffers{false};
|
||||
};
|
||||
|
||||
} // namespace Vulkan
|
||||
|
Reference in New Issue
Block a user