renderer_vulkan: Add suport for VK_EXT_debug_report

* Used in older android devices
This commit is contained in:
GPUCode
2023-01-19 23:19:55 +02:00
parent 1e3971038f
commit ab73566acc
5 changed files with 99 additions and 41 deletions

View File

@ -119,7 +119,7 @@ void Config::ReadValues() {
Settings::values.async_command_recording =
sdl2_config->GetBoolean("Renderer", "async_command_recording", true);
Settings::values.async_shader_compilation =
sdl2_config->GetBoolean("Renderer", "async_shader_compilation", true);
sdl2_config->GetBoolean("Renderer", "async_shader_compilation", false);
Settings::values.spirv_shader_gen =
sdl2_config->GetBoolean("Renderer", "spirv_shader_gen", true);
Settings::values.renderer_debug = sdl2_config->GetBoolean("Renderer", "renderer_debug", false);

View File

@ -15,9 +15,9 @@ namespace Vulkan {
vk::DynamicLoader Instance::dl;
static VKAPI_ATTR VkBool32 VKAPI_CALL
DebugHandler(VkDebugUtilsMessageSeverityFlagBitsEXT severity, VkDebugUtilsMessageTypeFlagsEXT type,
const VkDebugUtilsMessengerCallbackDataEXT* callback_data, void* user_data) {
static VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsCallback(
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
@ -49,6 +49,39 @@ DebugHandler(VkDebugUtilsMessageSeverityFlagBitsEXT severity, VkDebugUtilsMessag
return VK_FALSE;
}
static VKAPI_ATTR VkBool32 VKAPI_CALL 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);
Log::Level level{};
switch (severity) {
case VK_DEBUG_REPORT_ERROR_BIT_EXT:
level = Log::Level::Error;
break;
case VK_DEBUG_REPORT_INFORMATION_BIT_EXT:
level = Log::Level::Warning;
break;
case VK_DEBUG_REPORT_DEBUG_BIT_EXT:
case VK_DEBUG_REPORT_WARNING_BIT_EXT:
case VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT:
level = Log::Level::Debug;
break;
default:
level = Log::Level::Info;
}
const vk::DebugReportObjectTypeEXT type = static_cast<vk::DebugReportObjectTypeEXT>(objectType);
LOG_GENERIC(Log::Class::Render_Vulkan, level,
"type = {}, object = {} | MessageCode = {:#x}, LayerPrefix = {} | {}",
vk::to_string(type), object, messageCode, pLayerPrefix, pMessage);
return VK_FALSE;
}
vk::Format ToVkFormat(VideoCore::PixelFormat format) {
switch (format) {
case VideoCore::PixelFormat::RGBA8:
@ -86,7 +119,17 @@ vk::Format ToVkFormat(VideoCore::PixelFormat format) {
vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation |
vk::DebugUtilsMessageTypeFlagBitsEXT::eDeviceAddressBinding |
vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance,
.pfnUserCallback = DebugHandler,
.pfnUserCallback = DebugUtilsCallback,
};
}
[[nodiscard]] vk::DebugReportCallbackCreateInfoEXT MakeDebugReportCallbackInfo() {
return vk::DebugReportCallbackCreateInfoEXT{
.flags = vk::DebugReportFlagBitsEXT::eDebug | vk::DebugReportFlagBitsEXT::eInformation |
vk::DebugReportFlagBitsEXT::eError |
vk::DebugReportFlagBitsEXT::ePerformanceWarning |
vk::DebugReportFlagBitsEXT::eWarning,
.pfnCallback = DebugReportCallback,
};
}
@ -207,6 +250,24 @@ Instance::Instance(Frontend::EmuWindow& window, u32 physical_device_index)
MakeDebugUtilsMessengerInfo(),
};
const auto IsSupported = [&extensions](std::string_view requested) {
const auto it =
std::find_if(extensions.begin(), extensions.end(),
[requested](const char* extension) { return requested == extension; });
return it != extensions.end();
};
bool debug_messenger_supported{};
bool debug_report_supported{};
if (enable_validation) {
debug_messenger_supported = IsSupported(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
debug_report_supported = IsSupported(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
if (!debug_messenger_supported) {
instance_chain.unlink<vk::DebugUtilsMessengerCreateInfoEXT>();
}
}
try {
instance = vk::createInstance(instance_chain.get());
} catch (vk::LayerNotPresentError& err) {
@ -219,16 +280,10 @@ Instance::Instance(Frontend::EmuWindow& window, u32 physical_device_index)
// If validation is enabled attempt to also enable debug messenger
if (enable_validation) {
const auto it =
std::find_if(extensions.begin(), extensions.end(), [](const char* extension) {
return std::strcmp(extension, VK_EXT_DEBUG_UTILS_EXTENSION_NAME) == 0;
});
const bool debug_messenger_supported = it != extensions.end();
if (debug_messenger_supported) {
debug_messenger = instance.createDebugUtilsMessengerEXT(MakeDebugUtilsMessengerInfo());
} else {
instance_chain.unlink<vk::DebugUtilsMessengerCreateInfoEXT>();
} else if (debug_report_supported) {
callback = instance.createDebugReportCallbackEXT(MakeDebugReportCallbackInfo());
}
}
@ -262,6 +317,9 @@ Instance::~Instance() {
if (debug_messenger) {
instance.destroyDebugUtilsMessengerEXT(debug_messenger);
}
if (callback) {
instance.destroyDebugReportCallbackEXT(callback);
}
}
instance.destroy();

View File

@ -240,6 +240,7 @@ private:
vk::PhysicalDeviceLimits limits;
vk::DriverIdKHR driver_id;
vk::DebugUtilsMessengerEXT debug_messenger;
vk::DebugReportCallbackEXT callback;
std::string vendor_name;
VmaAllocator allocator;
vk::Queue present_queue;

View File

@ -141,6 +141,7 @@ std::vector<const char*> GetInstanceExtensions(Frontend::WindowSystemType window
if (enable_debug_utils) {
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
extensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
}
// Sanitize extension list
@ -151,8 +152,7 @@ std::vector<const char*> GetInstanceExtensions(Frontend::WindowSystemType window
});
if (it == properties.end()) {
LOG_WARNING(Render_Vulkan, "Required instance extension {} is not available",
extension);
LOG_INFO(Render_Vulkan, "Candidate instance extension {} is not available", extension);
return true;
}
return false;

View File

@ -461,6 +461,7 @@ void RasterizerVulkan::DrawTriangles() {
MICROPROFILE_DEFINE(Vulkan_Drawing, "Vulkan", "Drawing", MP_RGB(128, 128, 192));
bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) {
MICROPROFILE_SCOPE(Vulkan_Drawing);
const auto& regs = Pica::g_state.regs;
const bool shadow_rendering = regs.framebuffer.IsShadowRendering();
@ -674,32 +675,6 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) {
// NOTE: From here onwards its a safe zone to set the draw state, doing that any earlier will
// cause issues as the rasterizer cache might cause a scheduler switch and invalidate our state
// Sync the viewport
pipeline_cache.SetViewport(surfaces_rect.left + viewport_rect_unscaled.left * res_scale,
surfaces_rect.bottom + viewport_rect_unscaled.bottom * res_scale,
viewport_rect_unscaled.GetWidth() * res_scale,
viewport_rect_unscaled.GetHeight() * res_scale);
MICROPROFILE_SCOPE(Vulkan_Drawing);
// Sync and bind the shader
if (shader_dirty) {
pipeline_cache.UseFragmentShader(regs);
shader_dirty = false;
}
// Sync the LUTs within the texture buffer
SyncAndUploadLUTs();
SyncAndUploadLUTsLF();
// Sync the uniform data
UploadUniforms(accelerate);
// Viewport can have negative offsets or larger dimensions than our framebuffer sub-rect.
// Enable scissor test to prevent drawing outside of the framebuffer region
pipeline_cache.SetScissor(draw_rect.left, draw_rect.bottom, draw_rect.GetWidth(),
draw_rect.GetHeight());
// Sometimes the dimentions of the color and depth framebuffers might not be the same
// In that case select the minimum one to abide by the spec
u32 width = 0;
@ -742,6 +717,30 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) {
renderpass_cache.EnterRenderpass(renderpass_info);
// Sync and bind the shader
if (shader_dirty) {
pipeline_cache.UseFragmentShader(regs);
shader_dirty = false;
}
// Sync the LUTs within the texture buffer
SyncAndUploadLUTs();
SyncAndUploadLUTsLF();
// Sync the uniform data
UploadUniforms(accelerate);
// Sync the viewport
pipeline_cache.SetViewport(surfaces_rect.left + viewport_rect_unscaled.left * res_scale,
surfaces_rect.bottom + viewport_rect_unscaled.bottom * res_scale,
viewport_rect_unscaled.GetWidth() * res_scale,
viewport_rect_unscaled.GetHeight() * res_scale);
// Viewport can have negative offsets or larger dimensions than our framebuffer sub-rect.
// Enable scissor test to prevent drawing outside of the framebuffer region
pipeline_cache.SetScissor(draw_rect.left, draw_rect.bottom, draw_rect.GetWidth(),
draw_rect.GetHeight());
// Draw the vertex batch
bool succeeded = true;
if (accelerate) {