renderer_vulkan: Add suport for VK_EXT_debug_report
* Used in older android devices
This commit is contained in:
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
Reference in New Issue
Block a user