diff --git a/src/core/devtools/widget/frame_dump.cpp b/src/core/devtools/widget/frame_dump.cpp index 201ba0d3d..ab04ae4da 100644 --- a/src/core/devtools/widget/frame_dump.cpp +++ b/src/core/devtools/widget/frame_dump.cpp @@ -5,18 +5,50 @@ #include #include -#include "cmd_list.h" #include "frame_dump.h" #include "imgui_internal.h" using namespace ImGui; +using namespace DebugStateType; + +#define C_V(label, value, var, out) \ + if (Selectable(label, var == value)) { \ + var = value; \ + selected_cmd = -1; \ + out = true; \ + } + +// 00 to 99 +static std::array small_int_to_str(s8 i) { + std::array label{}; + if (i == -1) { + label[0] = 'N'; + label[1] = 'A'; + } else { + label[0] = i / 10 + '0'; + label[1] = i % 10 + '0'; + } + return label; +} namespace Core::Devtools::Widget { -FrameDumpViewer::FrameDumpViewer(DebugStateType::FrameDump frame_dump) - : frame_dump(std::move(frame_dump)) { +FrameDumpViewer::FrameDumpViewer(FrameDump _frame_dump) : frame_dump(std::move(_frame_dump)) { static int unique_id = 0; id = unique_id++; + + selected_queue_type = QueueType::dcb; + selected_submit_num = 0; + selected_queue_num2 = 0; + + cmd_list_viewer.reserve(frame_dump.queues.size()); + for (const auto& cmd : frame_dump.queues) { + cmd_list_viewer.emplace_back(cmd.data); + if (cmd.type == QueueType::dcb && cmd.submit_num == selected_submit_num && + cmd.num2 == selected_queue_num2) { + selected_cmd = cmd_list_viewer.size() - 1; + } + } } void FrameDumpViewer::Draw() { @@ -33,20 +65,86 @@ void FrameDumpViewer::Draw() { auto window = GetCurrentWindow(); SetWindowSize(window, ImVec2{450.0f, 500.0f}); } - if (BeginTabBar("Queues")) { - for (auto& cmd : frame_dump.queues) { - char tab_name[64]; - snprintf(tab_name, sizeof(tab_name), "%s - %d %d", - magic_enum::enum_name(cmd.type).data(), cmd.submit_num, cmd.num2); - if (BeginTabItem(tab_name)) { - CmdListViewer(cmd.data).Draw(); - EndTabItem(); + BeginGroup(); + TextEx("Queue type"); + SameLine(); + if (BeginCombo("##select_queue_type", magic_enum::enum_name(selected_queue_type).data(), + ImGuiComboFlags_WidthFitPreview)) { + bool selected = false; +#define COMBO(x) C_V(magic_enum::enum_name(x).data(), x, selected_queue_type, selected) + COMBO(QueueType::acb) + COMBO(QueueType::dcb); + COMBO(QueueType::ccb); + if (selected) { + selected_submit_num = selected_queue_num2 = -1; + } + EndCombo(); + } + SameLine(); + TextEx("Submit num"); + SameLine(); + if (BeginCombo("##select_submit_num", small_int_to_str(selected_submit_num).data(), + ImGuiComboFlags_WidthFitPreview)) { + std::array available_submits{}; + for (const auto& cmd : frame_dump.queues) { + if (cmd.type == selected_queue_type) { + available_submits[cmd.submit_num] = true; } } - EndTabBar(); + bool selected = false; + for (int i = 0; i < available_submits.size(); ++i) { + if (available_submits[i]) { + char label[3]{}; + label[0] = i / 10 + '0'; + label[1] = i % 10 + '0'; + C_V(label, i, selected_submit_num, selected); + } + } + if (selected) { + selected_queue_num2 = -1; + } + EndCombo(); + } + SameLine(); + TextEx(selected_queue_type == QueueType::acb ? "Queue num" : "Buffer num"); + SameLine(); + if (BeginCombo("##select_queue_num2", small_int_to_str(selected_queue_num2).data(), + ImGuiComboFlags_WidthFitPreview)) { + std::array available_queues{}; + for (const auto& cmd : frame_dump.queues) { + if (cmd.type == selected_queue_type && cmd.submit_num == selected_submit_num) { + available_queues[cmd.num2] = true; + } + } + bool selected = false; + for (int i = 0; i < available_queues.size(); ++i) { + if (available_queues[i]) { + char label[3]{}; + label[0] = i / 10 + '0'; + label[1] = i % 10 + '0'; + C_V(label, i, selected_queue_num2, selected); + } + } + if (selected) { + const auto it = std::ranges::find_if(frame_dump.queues, [&](const auto& cmd) { + return cmd.type == selected_queue_type && + cmd.submit_num == selected_submit_num && cmd.num2 == selected_queue_num2; + }); + if (it != frame_dump.queues.end()) { + selected_cmd = std::distance(frame_dump.queues.begin(), it); + } + } + EndCombo(); + } + EndGroup(); + + if (selected_cmd != -1) { + cmd_list_viewer[selected_cmd].Draw(); } } End(); } -} // namespace Core::Devtools::Widget \ No newline at end of file +} // namespace Core::Devtools::Widget + +#undef C_V \ No newline at end of file diff --git a/src/core/devtools/widget/frame_dump.h b/src/core/devtools/widget/frame_dump.h index 63e5fe3a6..2cd0abe6c 100644 --- a/src/core/devtools/widget/frame_dump.h +++ b/src/core/devtools/widget/frame_dump.h @@ -3,6 +3,9 @@ #pragma once +#include + +#include "cmd_list.h" #include "core/debug_state.h" namespace Core::Devtools::Widget { @@ -11,6 +14,13 @@ class FrameDumpViewer { DebugStateType::FrameDump frame_dump; int id; + std::vector cmd_list_viewer; + + DebugStateType::QueueType selected_queue_type; + s32 selected_submit_num; + s32 selected_queue_num2; + s32 selected_cmd = -1; + public: bool is_open = true;