From 9fee8a666afbc4bb9f6e6b6d2c15b8c45549817e Mon Sep 17 00:00:00 2001 From: tomboylover93 <95257311+tomboylover93@users.noreply.github.com> Date: Mon, 27 Jan 2025 21:55:04 -0300 Subject: [PATCH] Add Vulkan debug options to the Debug tab --- src/common/config.cpp | 24 +++-- src/common/config.h | 9 +- src/emulator.cpp | 6 +- src/imgui/renderer/imgui_core.cpp | 4 +- src/imgui/renderer/texture_manager.cpp | 2 +- src/qt_gui/settings_dialog.cpp | 33 ++++++- src/qt_gui/settings_dialog.ui | 95 +++++++++++++------ src/qt_gui/translations/en.ts | 20 ++++ src/video_core/renderer_vulkan/vk_platform.h | 4 +- .../renderer_vulkan/vk_presenter.cpp | 14 +-- .../renderer_vulkan/vk_rasterizer.cpp | 16 ++-- 11 files changed, 162 insertions(+), 65 deletions(-) diff --git a/src/common/config.cpp b/src/common/config.cpp index a57b6d35c..70b062951 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -267,18 +267,28 @@ bool vkValidationGpuEnabled() { return vkValidationGpu; } -bool vkCrashDiagnosticEnabled() { +bool getVkCrashDiagnosticEnabled() { return vkCrashDiagnostic; } -bool vkHostMarkersEnabled() { - // Forced on when crash diagnostic enabled. - return vkHostMarkers || vkCrashDiagnostic; +bool getVkHostMarkersEnabled() { + return vkHostMarkers; } -bool vkGuestMarkersEnabled() { - // Forced on when crash diagnostic enabled. - return vkGuestMarkers || vkCrashDiagnostic; +bool getVkGuestMarkersEnabled() { + return vkGuestMarkers; +} + +void setVkCrashDiagnosticEnabled(bool enable) { + vkCrashDiagnostic = enable; +} + +void setVkHostMarkersEnabled(bool enable) { + vkHostMarkers = enable; +} + +void setVkGuestMarkersEnabled(bool enable) { + vkGuestMarkers = enable; } bool getSeparateUpdateEnabled() { diff --git a/src/common/config.h b/src/common/config.h index 15937606e..356cf77fc 100644 --- a/src/common/config.h +++ b/src/common/config.h @@ -106,9 +106,12 @@ void setRdocEnabled(bool enable); bool vkValidationEnabled(); bool vkValidationSyncEnabled(); bool vkValidationGpuEnabled(); -bool vkCrashDiagnosticEnabled(); -bool vkHostMarkersEnabled(); -bool vkGuestMarkersEnabled(); +bool getVkCrashDiagnosticEnabled(); +bool getVkHostMarkersEnabled(); +bool getVkGuestMarkersEnabled(); +void setVkCrashDiagnosticEnabled(bool enable); +void setVkHostMarkersEnabled(bool enable); +void setVkGuestMarkersEnabled(bool enable); // Gui void setMainWindowGeometry(u32 x, u32 y, u32 w, u32 h); diff --git a/src/emulator.cpp b/src/emulator.cpp index 97215c06f..321fdad4c 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -66,9 +66,9 @@ Emulator::Emulator() { LOG_INFO(Config, "Vulkan vkValidation: {}", Config::vkValidationEnabled()); LOG_INFO(Config, "Vulkan vkValidationSync: {}", Config::vkValidationSyncEnabled()); LOG_INFO(Config, "Vulkan vkValidationGpu: {}", Config::vkValidationGpuEnabled()); - LOG_INFO(Config, "Vulkan crashDiagnostics: {}", Config::vkCrashDiagnosticEnabled()); - LOG_INFO(Config, "Vulkan hostMarkers: {}", Config::vkHostMarkersEnabled()); - LOG_INFO(Config, "Vulkan guestMarkers: {}", Config::vkGuestMarkersEnabled()); + LOG_INFO(Config, "Vulkan crashDiagnostics: {}", Config::getVkCrashDiagnosticEnabled()); + LOG_INFO(Config, "Vulkan hostMarkers: {}", Config::getVkHostMarkersEnabled()); + LOG_INFO(Config, "Vulkan guestMarkers: {}", Config::getVkGuestMarkersEnabled()); LOG_INFO(Config, "Vulkan rdocEnable: {}", Config::isRdocEnabled()); // Create stdin/stdout/stderr diff --git a/src/imgui/renderer/imgui_core.cpp b/src/imgui/renderer/imgui_core.cpp index 26253822c..d9530dd70 100644 --- a/src/imgui/renderer/imgui_core.cpp +++ b/src/imgui/renderer/imgui_core.cpp @@ -208,7 +208,7 @@ void Render(const vk::CommandBuffer& cmdbuf, const vk::ImageView& image_view, return; } - if (Config::vkHostMarkersEnabled()) { + if (Config::getVkHostMarkersEnabled()) { cmdbuf.beginDebugUtilsLabelEXT(vk::DebugUtilsLabelEXT{ .pLabelName = "ImGui Render", }); @@ -233,7 +233,7 @@ void Render(const vk::CommandBuffer& cmdbuf, const vk::ImageView& image_view, cmdbuf.beginRendering(render_info); Vulkan::RenderDrawData(*draw_data, cmdbuf); cmdbuf.endRendering(); - if (Config::vkHostMarkersEnabled()) { + if (Config::getVkHostMarkersEnabled()) { cmdbuf.endDebugUtilsLabelEXT(); } } diff --git a/src/imgui/renderer/texture_manager.cpp b/src/imgui/renderer/texture_manager.cpp index d7516a3a5..e217cd130 100644 --- a/src/imgui/renderer/texture_manager.cpp +++ b/src/imgui/renderer/texture_manager.cpp @@ -152,7 +152,7 @@ void WorkerLoop() { g_job_list.pop_front(); g_job_list_mtx.unlock(); - if (Config::vkCrashDiagnosticEnabled()) { + if (Config::getVkCrashDiagnosticEnabled()) { // FIXME: Crash diagnostic hangs when building the command buffer here continue; } diff --git a/src/qt_gui/settings_dialog.cpp b/src/qt_gui/settings_dialog.cpp index b41fde745..d84afb755 100644 --- a/src/qt_gui/settings_dialog.cpp +++ b/src/qt_gui/settings_dialog.cpp @@ -285,6 +285,11 @@ SettingsDialog::SettingsDialog(std::span physical_devices, ui->vkValidationCheckBox->installEventFilter(this); ui->vkSyncValidationCheckBox->installEventFilter(this); ui->rdocCheckBox->installEventFilter(this); + ui->crashDiagnosticsCheckBox->installEventFilter(this); + ui->guestMarkersCheckBox->installEventFilter(this); + ui->hostMarkersCheckBox->installEventFilter(this); + ui->collectShaderCheckBox->installEventFilter(this); + ui->copyGPUBuffersCheckBox->installEventFilter(this); } } @@ -360,6 +365,15 @@ void SettingsDialog::LoadValuesFromConfig() { ui->vkSyncValidationCheckBox->setChecked( toml::find_or(data, "Vulkan", "validation_sync", false)); ui->rdocCheckBox->setChecked(toml::find_or(data, "Vulkan", "rdocEnable", false)); + ui->crashDiagnosticsCheckBox->setChecked( + toml::find_or(data, "Vulkan", "crashDiagnostic", false)); + ui->guestMarkersCheckBox->setChecked( + toml::find_or(data, "Vulkan", "guestMarkers", false)); + ui->hostMarkersCheckBox->setChecked(toml::find_or(data, "Vulkan", "hostMarkers", false)); + ui->copyGPUBuffersCheckBox->setChecked( + toml::find_or(data, "GPU", "copyGPUBuffers", false)); + ui->collectShaderCheckBox->setChecked( + toml::find_or(data, "Debug", "CollectShader", false)); ui->enableCompatibilityCheckBox->setChecked( toml::find_or(data, "General", "compatibilityEnabled", false)); ui->checkCompatibilityOnStartupCheckBox->setChecked( @@ -380,7 +394,7 @@ void SettingsDialog::LoadValuesFromConfig() { std::string chooseHomeTab = toml::find_or(data, "General", "chooseHomeTab", ""); ui->chooseHomeTabComboBox->setCurrentText(QString::fromStdString(chooseHomeTab)); - QStringList tabNames = {tr("General"), tr("Gui"), tr("Graphics"), tr("User"), + QStringList tabNames = {tr("General"), tr("GUI"), tr("Graphics"), tr("User"), tr("Input"), tr("Paths"), tr("Debug")}; QString chooseHomeTabQString = QString::fromStdString(chooseHomeTab); int indexTab = tabNames.indexOf(chooseHomeTabQString); @@ -549,8 +563,16 @@ void SettingsDialog::updateNoteTextEdit(const QString& elementName) { text = tr("vkValidationCheckBox"); } else if (elementName == "vkSyncValidationCheckBox") { text = tr("vkSyncValidationCheckBox"); - } else if (elementName == "rdocCheckBox") { - text = tr("rdocCheckBox"); + } else if (elementName == "crashDiagnosticsCheckBox") { + text = tr("crashDiagnosticsCheckBox"); + } else if (elementName == "guestMarkersCheckBox") { + text = tr("guestMarkersCheckBox"); + } else if (elementName == "hostMarkersCheckBox") { + text = tr("hostMarkersCheckBox"); + } else if (elementName == "copyGPUBuffersCheckBox") { + text = tr("copyGPUBuffersCheckBox"); + } else if (elementName == "collectShaderCheckBox") { + text = tr("collectShaderCheckBox"); } ui->descriptionText->setText(text.replace("\\n", "\n")); @@ -604,6 +626,11 @@ void SettingsDialog::UpdateSettings() { Config::setVkValidation(ui->vkValidationCheckBox->isChecked()); Config::setVkSyncValidation(ui->vkSyncValidationCheckBox->isChecked()); Config::setRdocEnabled(ui->rdocCheckBox->isChecked()); + Config::setVkHostMarkersEnabled(ui->hostMarkersCheckBox->isChecked()); + Config::setVkGuestMarkersEnabled(ui->guestMarkersCheckBox->isChecked()); + Config::setVkCrashDiagnosticEnabled(ui->crashDiagnosticsCheckBox->isChecked()); + Config::setCollectShaderForDebug(ui->collectShaderCheckBox->isChecked()); + Config::setCopyGPUCmdBuffers(ui->copyGPUBuffersCheckBox->isChecked()); Config::setAutoUpdate(ui->updateCheckBox->isChecked()); Config::setUpdateChannel(ui->updateComboBox->currentText().toStdString()); Config::setChooseHomeTab(ui->chooseHomeTabComboBox->currentText().toStdString()); diff --git a/src/qt_gui/settings_dialog.ui b/src/qt_gui/settings_dialog.ui index 5da6a8198..443d5841e 100644 --- a/src/qt_gui/settings_dialog.ui +++ b/src/qt_gui/settings_dialog.ui @@ -12,7 +12,7 @@ 0 0 970 - 600 + 750 @@ -74,7 +74,7 @@ 0 0 946 - 386 + 535 @@ -476,15 +476,15 @@ true - Gui + GUI 0 0 - 946 - 386 + 676 + 381 @@ -546,7 +546,7 @@ - Gui + GUI @@ -809,8 +809,8 @@ 0 0 - 946 - 386 + 563 + 143 @@ -1053,8 +1053,8 @@ 0 0 - 946 - 386 + 244 + 295 @@ -1197,8 +1197,8 @@ 0 0 - 946 - 386 + 475 + 253 @@ -1481,8 +1481,8 @@ 0 0 - 946 - 386 + 216 + 256 @@ -1571,11 +1571,11 @@ 0 0 - 946 - 386 + 534 + 477 - + @@ -1585,7 +1585,7 @@ 0 - + @@ -1728,20 +1728,57 @@ - - - Qt::Orientation::Vertical + + + + 0 + 0 + - - QSizePolicy::Policy::MinimumExpanding + + Advanced - - - 0 - 0 - + + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop - + + + + + Enable Crash Diagnostics + + + + + + + Collect Shaders + + + + + + + Copy GPU Buffers + + + + + + + Host Debug Markers + + + + + + + Guest Debug Markers + + + + + diff --git a/src/qt_gui/translations/en.ts b/src/qt_gui/translations/en.ts index 8b6c3c69f..e935a2ac2 100644 --- a/src/qt_gui/translations/en.ts +++ b/src/qt_gui/translations/en.ts @@ -928,6 +928,26 @@ rdocCheckBox Enable RenderDoc Debugging:\nIf enabled, the emulator will provide compatibility with Renderdoc to allow capture and analysis of the currently rendered frame. + + collectShaderCheckBox + You need this enabled to edit shaders with the debug menu (Ctrl + F10). + + + crashDiagnosticsCheckBox + Creates a .yaml file with info about the Vulkan state at the time of crashing.\nUseful for debugging 'Device lost' errors. If you have this enabled, you should enable Host AND Guest Debug Markers.\nDoes not work on Intel GPUs.\nYou need Vulkan Validation Layers enabled and the Vulkan SDK for this to work. + + + copyGPUBuffersCheckBox + Gets around race conditions involving GPU submits.\nMay or may not help with PM4 type 0 crashes. + + + hostMarkersCheckBox + Inserts emulator-side information like markers for specific AMDGPU commands around Vulkan commands, as well as giving resources debug names.\nIf you have this enabled, you should enable Crash Diagnostics.\nUseful for programs like RenderDoc. + + + guestMarkersCheckBox + Inserts any debug markers the game itself has added to the command buffer.\nIf you have this enabled, you should enable Crash Diagnostics.\nUseful for programs like RenderDoc. + saveDataBox Save Data Path:\nThe folder where game save data will be saved. diff --git a/src/video_core/renderer_vulkan/vk_platform.h b/src/video_core/renderer_vulkan/vk_platform.h index d05d12997..4e9587e46 100644 --- a/src/video_core/renderer_vulkan/vk_platform.h +++ b/src/video_core/renderer_vulkan/vk_platform.h @@ -33,7 +33,7 @@ concept VulkanHandleType = vk::isVulkanHandleType::value; template void SetObjectName(vk::Device device, const HandleType& handle, std::string_view debug_name) { - if (!Config::vkHostMarkersEnabled()) { + if (!Config::getVkHostMarkersEnabled()) { return; } const vk::DebugUtilsObjectNameInfoEXT name_info = { @@ -50,7 +50,7 @@ void SetObjectName(vk::Device device, const HandleType& handle, std::string_view template void SetObjectName(vk::Device device, const HandleType& handle, const char* format, const Args&... args) { - if (!Config::vkHostMarkersEnabled()) { + if (!Config::getVkHostMarkersEnabled()) { return; } const std::string debug_name = fmt::vformat(format, fmt::make_format_args(args...)); diff --git a/src/video_core/renderer_vulkan/vk_presenter.cpp b/src/video_core/renderer_vulkan/vk_presenter.cpp index 35ab4318a..c2be1c3e8 100644 --- a/src/video_core/renderer_vulkan/vk_presenter.cpp +++ b/src/video_core/renderer_vulkan/vk_presenter.cpp @@ -294,7 +294,7 @@ void Presenter::CreatePostProcessPipeline() { Presenter::Presenter(Frontend::WindowSDL& window_, AmdGpu::Liverpool* liverpool_) : window{window_}, liverpool{liverpool_}, instance{window, Config::getGpuId(), Config::vkValidationEnabled(), - Config::vkCrashDiagnosticEnabled()}, + Config::getVkCrashDiagnosticEnabled()}, draw_scheduler{instance}, present_scheduler{instance}, flip_scheduler{instance}, swapchain{instance, window}, rasterizer{std::make_unique(instance, draw_scheduler, liverpool)}, @@ -467,7 +467,7 @@ bool Presenter::ShowSplash(Frame* frame /*= nullptr*/) { draw_scheduler.EndRendering(); const auto cmdbuf = draw_scheduler.CommandBuffer(); - if (Config::vkHostMarkersEnabled()) { + if (Config::getVkHostMarkersEnabled()) { cmdbuf.beginDebugUtilsLabelEXT(vk::DebugUtilsLabelEXT{ .pLabelName = "ShowSplash", }); @@ -541,7 +541,7 @@ bool Presenter::ShowSplash(Frame* frame /*= nullptr*/) { .pImageMemoryBarriers = &post_barrier, }); - if (Config::vkHostMarkersEnabled()) { + if (Config::getVkHostMarkersEnabled()) { cmdbuf.endDebugUtilsLabelEXT(); } @@ -573,7 +573,7 @@ Frame* Presenter::PrepareFrameInternal(VideoCore::ImageId image_id, bool is_eop) auto& scheduler = is_eop ? draw_scheduler : flip_scheduler; scheduler.EndRendering(); const auto cmdbuf = scheduler.CommandBuffer(); - if (Config::vkHostMarkersEnabled()) { + if (Config::getVkHostMarkersEnabled()) { const auto label = fmt::format("PrepareFrameInternal:{}", image_id.index); cmdbuf.beginDebugUtilsLabelEXT(vk::DebugUtilsLabelEXT{ .pLabelName = label.c_str(), @@ -704,7 +704,7 @@ Frame* Presenter::PrepareFrameInternal(VideoCore::ImageId image_id, bool is_eop) .pImageMemoryBarriers = &post_barrier, }); - if (Config::vkHostMarkersEnabled()) { + if (Config::getVkHostMarkersEnabled()) { cmdbuf.endDebugUtilsLabelEXT(); } @@ -755,7 +755,7 @@ void Presenter::Present(Frame* frame, bool is_reusing_frame) { auto& scheduler = present_scheduler; const auto cmdbuf = scheduler.CommandBuffer(); - if (Config::vkHostMarkersEnabled()) { + if (Config::getVkHostMarkersEnabled()) { cmdbuf.beginDebugUtilsLabelEXT(vk::DebugUtilsLabelEXT{ .pLabelName = "Present", }); @@ -857,7 +857,7 @@ void Presenter::Present(Frame* frame, bool is_reusing_frame) { } } - if (Config::vkHostMarkersEnabled()) { + if (Config::getVkHostMarkersEnabled()) { cmdbuf.endDebugUtilsLabelEXT(); } diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 7a0652ed7..b83c0400f 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -1242,8 +1242,8 @@ void Rasterizer::UpdateViewportScissorState(const GraphicsPipeline& pipeline) { } void Rasterizer::ScopeMarkerBegin(const std::string_view& str, bool from_guest) { - if ((from_guest && !Config::vkGuestMarkersEnabled()) || - (!from_guest && !Config::vkHostMarkersEnabled())) { + if ((from_guest && !Config::getVkGuestMarkersEnabled()) || + (!from_guest && !Config::getVkHostMarkersEnabled())) { return; } const auto cmdbuf = scheduler.CommandBuffer(); @@ -1253,8 +1253,8 @@ void Rasterizer::ScopeMarkerBegin(const std::string_view& str, bool from_guest) } void Rasterizer::ScopeMarkerEnd(bool from_guest) { - if ((from_guest && !Config::vkGuestMarkersEnabled()) || - (!from_guest && !Config::vkHostMarkersEnabled())) { + if ((from_guest && !Config::getVkGuestMarkersEnabled()) || + (!from_guest && !Config::getVkHostMarkersEnabled())) { return; } const auto cmdbuf = scheduler.CommandBuffer(); @@ -1262,8 +1262,8 @@ void Rasterizer::ScopeMarkerEnd(bool from_guest) { } void Rasterizer::ScopedMarkerInsert(const std::string_view& str, bool from_guest) { - if ((from_guest && !Config::vkGuestMarkersEnabled()) || - (!from_guest && !Config::vkHostMarkersEnabled())) { + if ((from_guest && !Config::getVkGuestMarkersEnabled()) || + (!from_guest && !Config::getVkHostMarkersEnabled())) { return; } const auto cmdbuf = scheduler.CommandBuffer(); @@ -1274,8 +1274,8 @@ void Rasterizer::ScopedMarkerInsert(const std::string_view& str, bool from_guest void Rasterizer::ScopedMarkerInsertColor(const std::string_view& str, const u32 color, bool from_guest) { - if ((from_guest && !Config::vkGuestMarkersEnabled()) || - (!from_guest && !Config::vkHostMarkersEnabled())) { + if ((from_guest && !Config::getVkGuestMarkersEnabled()) || + (!from_guest && !Config::getVkHostMarkersEnabled())) { return; } const auto cmdbuf = scheduler.CommandBuffer();