diff --git a/src/core/debug_state.h b/src/core/debug_state.h index 3b1837d92..00c687fa5 100644 --- a/src/core/debug_state.h +++ b/src/core/debug_state.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "common/types.h" @@ -66,6 +67,8 @@ class DebugStateImpl { std::mutex frame_dump_list_mutex; std::vector frame_dump_list{}; + std::queue debug_message_popup; + public: void AddCurrentThreadToGuestList(); @@ -110,6 +113,13 @@ public: std::unique_lock lock{frame_dump_list_mutex}; GetFrameDump().queues.push_back(std::move(dump)); } + + void ShowDebugMessage(std::string message) { + if (message.empty()) { + return; + } + debug_message_popup.push(std::move(message)); + } }; } // namespace DebugStateType diff --git a/src/core/devtools/layer.cpp b/src/core/devtools/layer.cpp index 141a8e80a..88115e946 100644 --- a/src/core/devtools/layer.cpp +++ b/src/core/devtools/layer.cpp @@ -25,6 +25,8 @@ static int dump_frame_count = 1; static Widget::FrameGraph frame_graph; static std::vector frame_viewers; +static float debug_popup_timing = 3.0f; + void L::DrawMenuBar() { const auto& ctx = *GImGui; const auto& io = ctx.IO; @@ -105,6 +107,30 @@ void L::DrawAdvanced() { it = frame_viewers.erase(it); } } + + if (!DebugState.debug_message_popup.empty()) { + if (debug_popup_timing > 0.0f) { + debug_popup_timing -= io.DeltaTime; + if (Begin("##devtools_msg", nullptr, + ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoSavedSettings | + ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoMove)) { + BringWindowToDisplayFront(GetCurrentWindow()); + const auto display_size = io.DisplaySize; + const auto& msg = DebugState.debug_message_popup.front(); + const auto padding = GetStyle().WindowPadding; + const auto txt_size = CalcTextSize(&msg.front(), &msg.back() + 1, false, 250.0f); + SetWindowPos({display_size.x - padding.x * 2.0f - txt_size.x, 50.0f}); + SetWindowSize({txt_size.x + padding.x * 2.0f, txt_size.y + padding.y * 2.0f}); + PushTextWrapPos(250.0f); + TextEx(&msg.front(), &msg.back() + 1); + PopTextWrapPos(); + } + End(); + } else { + DebugState.debug_message_popup.pop(); + debug_popup_timing = 3.0f; + } + } } void L::DrawSimple() { diff --git a/src/core/devtools/widget/frame_dump.cpp b/src/core/devtools/widget/frame_dump.cpp index 5d9977a62..d27bab90a 100644 --- a/src/core/devtools/widget/frame_dump.cpp +++ b/src/core/devtools/widget/frame_dump.cpp @@ -2,9 +2,11 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include +#include #include #include +#include "common/io_file.h" #include "frame_dump.h" #include "imgui_internal.h" #include "imgui_memory_editor.h" @@ -20,7 +22,7 @@ using namespace DebugStateType; } // 00 to 99 -static std::array small_int_to_str(s8 i) { +static std::array small_int_to_str(const s32 i) { std::array label{}; if (i == -1) { label[0] = 'N'; @@ -69,7 +71,7 @@ void FrameDumpViewer::Draw() { if (Begin(name, &is_open, ImGuiWindowFlags_NoSavedSettings)) { if (IsWindowAppearing()) { auto window = GetCurrentWindow(); - SetWindowSize(window, ImVec2{450.0f, 500.0f}); + SetWindowSize(window, ImVec2{470.0f, 600.0f}); } BeginGroup(); TextEx("Queue type"); @@ -142,6 +144,24 @@ void FrameDumpViewer::Draw() { } EndCombo(); } + SameLine(); + BeginDisabled(selected_cmd == -1); + if (SmallButton("Dump cmd")) { + auto now_time = fmt::localtime(std::time(nullptr)); + const auto fname = fmt::format("{:%F %H-%M-%S} {}_{}_{}.bin", now_time, + magic_enum::enum_name(selected_queue_type), + selected_submit_num, selected_queue_num2); + Common::FS::IOFile file(fname, Common::FS::FileAccessMode::Write); + auto& data = frame_dump.queues[selected_cmd].data; + if (file.IsOpen()) { + DebugState.ShowDebugMessage(fmt::format("Dumping cmd as {}", fname)); + file.Write(data); + } else { + DebugState.ShowDebugMessage(fmt::format("Failed to save {}", fname)); + LOG_ERROR(Core, "Failed to open file {}", fname); + } + } + EndDisabled(); EndGroup(); if (selected_cmd != -1) {