mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-04 08:22:32 +00:00
devtools: option to show collapsed frame dump
keep most popups open when selection changes best popup windows positioning
This commit is contained in:
parent
d56abb0026
commit
eddbe59793
@ -36,9 +36,9 @@ class FrameGraph;
|
|||||||
namespace DebugStateType {
|
namespace DebugStateType {
|
||||||
|
|
||||||
enum class QueueType {
|
enum class QueueType {
|
||||||
acb,
|
dcb = 0,
|
||||||
dcb,
|
ccb = 1,
|
||||||
ccb,
|
acb = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct QueueDump {
|
struct QueueDump {
|
||||||
|
@ -154,20 +154,28 @@ void L::DrawAdvanced() {
|
|||||||
if (BeginPopupModal("GPU Tools Options", &close_popup_options,
|
if (BeginPopupModal("GPU Tools Options", &close_popup_options,
|
||||||
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings)) {
|
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings)) {
|
||||||
static char disassembly_cli[512];
|
static char disassembly_cli[512];
|
||||||
|
static bool frame_dump_render_on_collapse;
|
||||||
|
|
||||||
if (just_opened_options) {
|
if (just_opened_options) {
|
||||||
just_opened_options = false;
|
just_opened_options = false;
|
||||||
auto s = Options.disassembly_cli.copy(disassembly_cli, sizeof(disassembly_cli) - 1);
|
auto s = Options.disassembly_cli.copy(disassembly_cli, sizeof(disassembly_cli) - 1);
|
||||||
disassembly_cli[s] = '\0';
|
disassembly_cli[s] = '\0';
|
||||||
|
frame_dump_render_on_collapse = Options.frame_dump_render_on_collapse;
|
||||||
}
|
}
|
||||||
|
|
||||||
InputText("Shader disassembler: ", disassembly_cli, sizeof(disassembly_cli));
|
InputText("Shader disassembler: ", disassembly_cli, sizeof(disassembly_cli));
|
||||||
if (IsItemHovered()) {
|
if (IsItemHovered()) {
|
||||||
SetTooltip(R"(Command to disassemble shaders. Example "dis.exe" --raw "{src}")");
|
SetTooltip(R"(Command to disassemble shaders. Example "dis.exe" --raw "{src}")");
|
||||||
}
|
}
|
||||||
|
Checkbox("Show frame dump popups even when collapsed", &frame_dump_render_on_collapse);
|
||||||
|
if (IsItemHovered()) {
|
||||||
|
SetTooltip("When a frame dump is collapsed, it will keep\n"
|
||||||
|
"showing all opened popups related to it");
|
||||||
|
}
|
||||||
|
|
||||||
if (Button("Save")) {
|
if (Button("Save")) {
|
||||||
Options.disassembly_cli = disassembly_cli;
|
Options.disassembly_cli = disassembly_cli;
|
||||||
|
Options.frame_dump_render_on_collapse = frame_dump_render_on_collapse;
|
||||||
SaveIniSettingsToDisk(io.IniFilename);
|
SaveIniSettingsToDisk(io.IniFilename);
|
||||||
CloseCurrentPopup();
|
CloseCurrentPopup();
|
||||||
}
|
}
|
||||||
|
@ -11,14 +11,20 @@ TOptions Options;
|
|||||||
|
|
||||||
void LoadOptionsConfig(const char* line) {
|
void LoadOptionsConfig(const char* line) {
|
||||||
char str[512];
|
char str[512];
|
||||||
|
int i;
|
||||||
if (sscanf(line, "disassembly_cli=%511[^\n]", str) == 1) {
|
if (sscanf(line, "disassembly_cli=%511[^\n]", str) == 1) {
|
||||||
Options.disassembly_cli = str;
|
Options.disassembly_cli = str;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (sscanf(line, "frame_dump_render_on_collapse=%d", &i) == 1) {
|
||||||
|
Options.frame_dump_render_on_collapse = i != 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializeOptionsConfig(ImGuiTextBuffer* buf) {
|
void SerializeOptionsConfig(ImGuiTextBuffer* buf) {
|
||||||
buf->appendf("disassembly_cli=%s\n", Options.disassembly_cli.c_str());
|
buf->appendf("disassembly_cli=%s\n", Options.disassembly_cli.c_str());
|
||||||
|
buf->appendf("frame_dump_render_on_collapse=%d\n", Options.frame_dump_render_on_collapse);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Core::Devtools
|
} // namespace Core::Devtools
|
||||||
|
@ -10,7 +10,8 @@ struct ImGuiTextBuffer;
|
|||||||
namespace Core::Devtools {
|
namespace Core::Devtools {
|
||||||
|
|
||||||
struct TOptions {
|
struct TOptions {
|
||||||
std::string disassembly_cli;
|
std::string disassembly_cli{};
|
||||||
|
bool frame_dump_render_on_collapse{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
extern TOptions Options;
|
extern TOptions Options;
|
||||||
|
@ -1173,7 +1173,7 @@ CmdListViewer::CmdListViewer(DebugStateType::FrameDump* _frame_dump,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmdListViewer::Draw() {
|
void CmdListViewer::Draw(bool only_batches_view) {
|
||||||
const auto& ctx = *GetCurrentContext();
|
const auto& ctx = *GetCurrentContext();
|
||||||
|
|
||||||
if (batch_view.open) {
|
if (batch_view.open) {
|
||||||
@ -1188,6 +1188,10 @@ void CmdListViewer::Draw() {
|
|||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (only_batches_view) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (cmdb_view.Open) {
|
if (cmdb_view.Open) {
|
||||||
MemoryEditor::Sizes s;
|
MemoryEditor::Sizes s;
|
||||||
cmdb_view.CalcSizes(s, cmdb_size, cmdb_addr);
|
cmdb_view.CalcSizes(s, cmdb_size, cmdb_addr);
|
||||||
@ -1313,12 +1317,17 @@ void CmdListViewer::Draw() {
|
|||||||
pop.SetData(data, name, batch_id);
|
pop.SetData(data, name, batch_id);
|
||||||
pop.open = true;
|
pop.open = true;
|
||||||
} else {
|
} else {
|
||||||
|
if (batch_view.open &&
|
||||||
|
this->last_selected_batch == static_cast<int>(batch_id)) {
|
||||||
|
batch_view.open = false;
|
||||||
|
} else {
|
||||||
|
this->last_selected_batch = static_cast<int>(batch_id);
|
||||||
batch_view.SetData(data, name, batch_id);
|
batch_view.SetData(data, name, batch_id);
|
||||||
if (!batch_view.open) {
|
if (!batch_view.open || !batch_view.moved) {
|
||||||
batch_view.open = true;
|
batch_view.open = true;
|
||||||
const auto pos = GImGui->LastItemData.Rect.Max + ImVec2(5.0f, 0.0f);
|
const auto pos = GetItemRectMax() + ImVec2{5.0f, 0.0f};
|
||||||
SetNextWindowPos(pos, ImGuiCond_Always);
|
batch_view.SetPos(pos);
|
||||||
batch_view.Draw();
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1330,7 +1339,10 @@ void CmdListViewer::Draw() {
|
|||||||
show_batch_content =
|
show_batch_content =
|
||||||
CollapsingHeader(batch_hdr, ImGuiTreeNodeFlags_AllowOverlap);
|
CollapsingHeader(batch_hdr, ImGuiTreeNodeFlags_AllowOverlap);
|
||||||
SameLine(GetContentRegionAvail().x - 40.0f);
|
SameLine(GetContentRegionAvail().x - 40.0f);
|
||||||
if (Button("->", {40.0f, 0.0f})) {
|
const char* text =
|
||||||
|
last_selected_batch == static_cast<int>(batch_id) && batch_view.open ? "X"
|
||||||
|
: "->";
|
||||||
|
if (Button(text, {40.0f, 0.0f})) {
|
||||||
open_batch_view();
|
open_batch_view();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1360,7 +1372,12 @@ void CmdListViewer::Draw() {
|
|||||||
if (!group_batches) {
|
if (!group_batches) {
|
||||||
if (IsDrawCall(op)) {
|
if (IsDrawCall(op)) {
|
||||||
SameLine(GetContentRegionAvail().x - 40.0f);
|
SameLine(GetContentRegionAvail().x - 40.0f);
|
||||||
if (Button("->", {40.0f, 0.0f})) {
|
const char* text =
|
||||||
|
last_selected_batch == static_cast<int>(batch_id) &&
|
||||||
|
batch_view.open
|
||||||
|
? "X"
|
||||||
|
: "->";
|
||||||
|
if (Button(text, {40.0f, 0.0f})) {
|
||||||
open_batch_view();
|
open_batch_view();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,8 @@ class CmdListViewer {
|
|||||||
u32 highlight_batch{~0u};
|
u32 highlight_batch{~0u};
|
||||||
|
|
||||||
RegView batch_view;
|
RegView batch_view;
|
||||||
|
int last_selected_batch{-1};
|
||||||
|
|
||||||
std::vector<RegView> extra_batch_view;
|
std::vector<RegView> extra_batch_view;
|
||||||
|
|
||||||
static void OnNop(AmdGpu::PM4Type3Header const* header, u32 const* body);
|
static void OnNop(AmdGpu::PM4Type3Header const* header, u32 const* body);
|
||||||
@ -68,7 +70,7 @@ public:
|
|||||||
explicit CmdListViewer(DebugStateType::FrameDump* frame_dump, const std::vector<u32>& cmd_list,
|
explicit CmdListViewer(DebugStateType::FrameDump* frame_dump, const std::vector<u32>& cmd_list,
|
||||||
uintptr_t base_addr = 0, std::string name = "");
|
uintptr_t base_addr = 0, std::string name = "");
|
||||||
|
|
||||||
void Draw();
|
void Draw(bool only_batches_view = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Core::Devtools::Widget
|
} // namespace Core::Devtools::Widget
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <magic_enum.hpp>
|
#include <magic_enum.hpp>
|
||||||
|
|
||||||
#include "common/io_file.h"
|
#include "common/io_file.h"
|
||||||
|
#include "core/devtools/options.h"
|
||||||
#include "frame_dump.h"
|
#include "frame_dump.h"
|
||||||
#include "imgui_internal.h"
|
#include "imgui_internal.h"
|
||||||
#include "imgui_memory_editor.h"
|
#include "imgui_memory_editor.h"
|
||||||
@ -45,11 +46,14 @@ FrameDumpViewer::FrameDumpViewer(const FrameDump& _frame_dump)
|
|||||||
selected_submit_num = 0;
|
selected_submit_num = 0;
|
||||||
selected_queue_num2 = 0;
|
selected_queue_num2 = 0;
|
||||||
|
|
||||||
|
has_queue_type.fill(false);
|
||||||
cmd_list_viewer.reserve(frame_dump->queues.size());
|
cmd_list_viewer.reserve(frame_dump->queues.size());
|
||||||
for (const auto& cmd : frame_dump->queues) {
|
for (const auto& cmd : frame_dump->queues) {
|
||||||
|
if (!cmd.data.empty()) {
|
||||||
|
has_queue_type[static_cast<s32>(cmd.type)] = true;
|
||||||
|
}
|
||||||
const auto fname = fmt::format("F{} {}_{:02}_{:02}", frame_dump->frame_id,
|
const auto fname = fmt::format("F{} {}_{:02}_{:02}", frame_dump->frame_id,
|
||||||
magic_enum::enum_name(selected_queue_type),
|
magic_enum::enum_name(cmd.type), cmd.submit_num, cmd.num2);
|
||||||
selected_submit_num, selected_queue_num2);
|
|
||||||
cmd_list_viewer.emplace_back(frame_dump.get(), cmd.data, cmd.base_addr, fname);
|
cmd_list_viewer.emplace_back(frame_dump.get(), cmd.data, cmd.base_addr, fname);
|
||||||
if (cmd.type == QueueType::dcb && cmd.submit_num == 0 && cmd.num2 == 0) {
|
if (cmd.type == QueueType::dcb && cmd.submit_num == 0 && cmd.num2 == 0) {
|
||||||
selected_cmd = static_cast<s32>(cmd_list_viewer.size() - 1);
|
selected_cmd = static_cast<s32>(cmd_list_viewer.size() - 1);
|
||||||
@ -64,9 +68,28 @@ void FrameDumpViewer::Draw() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto try_select = [&, this] {
|
||||||
|
const auto it = std::ranges::find_if(frame_dump->queues, [&](const auto& cmd) {
|
||||||
|
return cmd.type == selected_queue_type &&
|
||||||
|
(selected_submit_num == -1 || cmd.submit_num == selected_submit_num) &&
|
||||||
|
(selected_queue_num2 == -1 || cmd.num2 == selected_queue_num2);
|
||||||
|
});
|
||||||
|
if (it != frame_dump->queues.end()) {
|
||||||
|
selected_cmd = static_cast<s32>(std::distance(frame_dump->queues.begin(), it));
|
||||||
|
selected_submit_num = static_cast<s32>(frame_dump->queues[selected_cmd].submit_num);
|
||||||
|
selected_queue_num2 = static_cast<s32>(frame_dump->queues[selected_cmd].num2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool is_showing = Options.frame_dump_render_on_collapse;
|
||||||
|
bool is_collapsed = true;
|
||||||
|
|
||||||
char name[32];
|
char name[32];
|
||||||
snprintf(name, sizeof(name), "Frame #%d dump", frame_dump->frame_id);
|
snprintf(name, sizeof(name), "Frame #%d dump", frame_dump->frame_id);
|
||||||
if (Begin(name, &is_open, ImGuiWindowFlags_NoSavedSettings)) {
|
if (Begin(name, &is_open, ImGuiWindowFlags_NoSavedSettings)) {
|
||||||
|
is_showing = true;
|
||||||
|
is_collapsed = false;
|
||||||
|
|
||||||
if (IsWindowAppearing()) {
|
if (IsWindowAppearing()) {
|
||||||
auto window = GetCurrentWindow();
|
auto window = GetCurrentWindow();
|
||||||
static ImGuiID dock_id = ImHashStr("FrameDumpDock");
|
static ImGuiID dock_id = ImHashStr("FrameDumpDock");
|
||||||
@ -79,12 +102,15 @@ void FrameDumpViewer::Draw() {
|
|||||||
if (BeginCombo("##select_queue_type", magic_enum::enum_name(selected_queue_type).data(),
|
if (BeginCombo("##select_queue_type", magic_enum::enum_name(selected_queue_type).data(),
|
||||||
ImGuiComboFlags_WidthFitPreview)) {
|
ImGuiComboFlags_WidthFitPreview)) {
|
||||||
bool selected = false;
|
bool selected = false;
|
||||||
#define COMBO(x) C_V(magic_enum::enum_name(x).data(), x, selected_queue_type, selected)
|
#define COMBO(x) \
|
||||||
COMBO(QueueType::acb)
|
if (has_queue_type[static_cast<s32>(x)]) \
|
||||||
|
C_V(magic_enum::enum_name(x).data(), x, selected_queue_type, selected)
|
||||||
COMBO(QueueType::dcb);
|
COMBO(QueueType::dcb);
|
||||||
COMBO(QueueType::ccb);
|
COMBO(QueueType::ccb);
|
||||||
|
COMBO(QueueType::acb);
|
||||||
if (selected) {
|
if (selected) {
|
||||||
selected_submit_num = selected_queue_num2 = -1;
|
selected_submit_num = selected_queue_num2 = -1;
|
||||||
|
try_select();
|
||||||
}
|
}
|
||||||
EndCombo();
|
EndCombo();
|
||||||
}
|
}
|
||||||
@ -111,9 +137,9 @@ void FrameDumpViewer::Draw() {
|
|||||||
SameLine();
|
SameLine();
|
||||||
if (BeginCombo("##select_submit_num", small_int_to_str(selected_submit_num).data(),
|
if (BeginCombo("##select_submit_num", small_int_to_str(selected_submit_num).data(),
|
||||||
ImGuiComboFlags_WidthFitPreview)) {
|
ImGuiComboFlags_WidthFitPreview)) {
|
||||||
std::array<bool, 32> available_submits{};
|
std::array<bool, 32> available_submits{false};
|
||||||
for (const auto& cmd : frame_dump->queues) {
|
for (const auto& cmd : frame_dump->queues) {
|
||||||
if (cmd.type == selected_queue_type) {
|
if (cmd.type == selected_queue_type && !cmd.data.empty()) {
|
||||||
available_submits[cmd.submit_num] = true;
|
available_submits[cmd.submit_num] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -128,6 +154,7 @@ void FrameDumpViewer::Draw() {
|
|||||||
}
|
}
|
||||||
if (selected) {
|
if (selected) {
|
||||||
selected_queue_num2 = -1;
|
selected_queue_num2 = -1;
|
||||||
|
try_select();
|
||||||
}
|
}
|
||||||
EndCombo();
|
EndCombo();
|
||||||
}
|
}
|
||||||
@ -136,9 +163,10 @@ void FrameDumpViewer::Draw() {
|
|||||||
SameLine();
|
SameLine();
|
||||||
if (BeginCombo("##select_queue_num2", small_int_to_str(selected_queue_num2).data(),
|
if (BeginCombo("##select_queue_num2", small_int_to_str(selected_queue_num2).data(),
|
||||||
ImGuiComboFlags_WidthFitPreview)) {
|
ImGuiComboFlags_WidthFitPreview)) {
|
||||||
std::array<bool, 32> available_queues{};
|
std::array<bool, 32> available_queues{false};
|
||||||
for (const auto& cmd : frame_dump->queues) {
|
for (const auto& cmd : frame_dump->queues) {
|
||||||
if (cmd.type == selected_queue_type && cmd.submit_num == selected_submit_num) {
|
if (cmd.type == selected_queue_type && cmd.submit_num == selected_submit_num &&
|
||||||
|
!cmd.data.empty()) {
|
||||||
available_queues[cmd.num2] = true;
|
available_queues[cmd.num2] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -152,21 +180,14 @@ void FrameDumpViewer::Draw() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (selected) {
|
if (selected) {
|
||||||
const auto it = std::ranges::find_if(frame_dump->queues, [&](const auto& cmd) {
|
try_select();
|
||||||
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 = static_cast<s32>(std::distance(frame_dump->queues.begin(), it));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
EndCombo();
|
EndCombo();
|
||||||
}
|
}
|
||||||
EndGroup();
|
EndGroup();
|
||||||
|
|
||||||
if (selected_cmd != -1) {
|
|
||||||
cmd_list_viewer[selected_cmd].Draw();
|
|
||||||
}
|
}
|
||||||
|
if (is_showing && selected_cmd != -1) {
|
||||||
|
cmd_list_viewer[selected_cmd].Draw(is_collapsed);
|
||||||
}
|
}
|
||||||
End();
|
End();
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ class FrameDumpViewer {
|
|||||||
int id;
|
int id;
|
||||||
|
|
||||||
std::vector<CmdListViewer> cmd_list_viewer;
|
std::vector<CmdListViewer> cmd_list_viewer;
|
||||||
|
std::array<bool, 3> has_queue_type;
|
||||||
|
|
||||||
DebugStateType::QueueType selected_queue_type;
|
DebugStateType::QueueType selected_queue_type;
|
||||||
s32 selected_submit_num;
|
s32 selected_submit_num;
|
||||||
|
@ -154,21 +154,36 @@ void RegPopup::SetData(const std::string& base_title, AmdGpu::Liverpool::DepthBu
|
|||||||
this->title = fmt::format("{}/Depth", base_title);
|
this->title = fmt::format("{}/Depth", base_title);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegPopup::Draw(bool auto_resize) {
|
void RegPopup::SetPos(ImVec2 pos, bool auto_resize) {
|
||||||
char name[128];
|
char name[128];
|
||||||
snprintf(name, sizeof(name), "%s###reg_popup_%d", title.c_str(), id);
|
snprintf(name, sizeof(name), "%s###reg_popup_%d", title.c_str(), id);
|
||||||
if (Begin(title.c_str(), &open, flags)) {
|
Begin(name, &open, flags);
|
||||||
if (const auto* buffer = std::get_if<AmdGpu::Liverpool::ColorBuffer>(&data)) {
|
SetWindowPos(pos);
|
||||||
if (auto_resize) {
|
if (auto_resize) {
|
||||||
|
if (std::holds_alternative<AmdGpu::Liverpool::ColorBuffer>(data)) {
|
||||||
SetWindowSize({365.0f, 520.0f});
|
SetWindowSize({365.0f, 520.0f});
|
||||||
KeepWindowInside();
|
KeepWindowInside();
|
||||||
}
|
} else if (std::holds_alternative<DepthBuffer>(data)) {
|
||||||
DrawColorBuffer(*buffer);
|
|
||||||
} else if (const auto* depth_data = std::get_if<DepthBuffer>(&data)) {
|
|
||||||
if (auto_resize) {
|
|
||||||
SetWindowSize({404.0f, 543.0f});
|
SetWindowSize({404.0f, 543.0f});
|
||||||
KeepWindowInside();
|
KeepWindowInside();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
last_pos = GetWindowPos();
|
||||||
|
moved = false;
|
||||||
|
End();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegPopup::Draw() {
|
||||||
|
char name[128];
|
||||||
|
snprintf(name, sizeof(name), "%s###reg_popup_%d", title.c_str(), id);
|
||||||
|
if (Begin(name, &open, flags)) {
|
||||||
|
if (GetWindowPos() != last_pos) {
|
||||||
|
moved = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const auto* buffer = std::get_if<AmdGpu::Liverpool::ColorBuffer>(&data)) {
|
||||||
|
DrawColorBuffer(*buffer);
|
||||||
|
} else if (const auto* depth_data = std::get_if<DepthBuffer>(&data)) {
|
||||||
DrawDepthBuffer(*depth_data);
|
DrawDepthBuffer(*depth_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ class RegPopup {
|
|||||||
|
|
||||||
using DepthBuffer = std::tuple<AmdGpu::Liverpool::DepthBuffer, AmdGpu::Liverpool::DepthControl>;
|
using DepthBuffer = std::tuple<AmdGpu::Liverpool::DepthBuffer, AmdGpu::Liverpool::DepthControl>;
|
||||||
|
|
||||||
|
ImVec2 last_pos;
|
||||||
std::variant<AmdGpu::Liverpool::ColorBuffer, DepthBuffer> data;
|
std::variant<AmdGpu::Liverpool::ColorBuffer, DepthBuffer> data;
|
||||||
std::string title{};
|
std::string title{};
|
||||||
|
|
||||||
@ -27,6 +28,7 @@ class RegPopup {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
bool open = false;
|
bool open = false;
|
||||||
|
bool moved = false;
|
||||||
|
|
||||||
RegPopup();
|
RegPopup();
|
||||||
|
|
||||||
@ -36,7 +38,9 @@ public:
|
|||||||
void SetData(const std::string& base_title, AmdGpu::Liverpool::DepthBuffer depth_buffer,
|
void SetData(const std::string& base_title, AmdGpu::Liverpool::DepthBuffer depth_buffer,
|
||||||
AmdGpu::Liverpool::DepthControl depth_control);
|
AmdGpu::Liverpool::DepthControl depth_control);
|
||||||
|
|
||||||
void Draw(bool auto_resize = false);
|
void SetPos(ImVec2 pos, bool auto_resize = false);
|
||||||
|
|
||||||
|
void Draw();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Core::Devtools::Widget
|
} // namespace Core::Devtools::Widget
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
using namespace ImGui;
|
using namespace ImGui;
|
||||||
using magic_enum::enum_name;
|
using magic_enum::enum_name;
|
||||||
|
|
||||||
|
constexpr auto depth_id = 0xF3;
|
||||||
|
|
||||||
static std::optional<std::string> exec_cli(const char* cli) {
|
static std::optional<std::string> exec_cli(const char* cli) {
|
||||||
std::array<char, 64> buffer{};
|
std::array<char, 64> buffer{};
|
||||||
std::string output;
|
std::string output;
|
||||||
@ -110,21 +112,20 @@ void RegView::DrawRegs() {
|
|||||||
DrawRow("Color control", "%X (%s)", cc_mode, enum_name(cc_mode).data());
|
DrawRow("Color control", "%X (%s)", cc_mode, enum_name(cc_mode).data());
|
||||||
|
|
||||||
const auto open_new_popup = [&](int cb, auto... args) {
|
const auto open_new_popup = [&](int cb, auto... args) {
|
||||||
|
const auto pos = GetItemRectMax() + ImVec2(5.0f, 0.0f);
|
||||||
if (GetIO().KeyShift) {
|
if (GetIO().KeyShift) {
|
||||||
auto& pop = extra_reg_popup.emplace_back();
|
auto& pop = extra_reg_popup.emplace_back();
|
||||||
pop.SetData(title, args...);
|
pop.SetData(title, args...);
|
||||||
pop.open = true;
|
pop.open = true;
|
||||||
pop.Draw(true);
|
pop.SetPos(pos, true);
|
||||||
} else if (last_selected_cb == cb && default_reg_popup.open) {
|
} else if (last_selected_cb == cb && default_reg_popup.open) {
|
||||||
default_reg_popup.open = false;
|
default_reg_popup.open = false;
|
||||||
} else {
|
} else {
|
||||||
last_selected_cb = cb;
|
last_selected_cb = cb;
|
||||||
default_reg_popup.SetData(title, args...);
|
default_reg_popup.SetData(title, args...);
|
||||||
if (!default_reg_popup.open) {
|
if (!default_reg_popup.open || !default_reg_popup.moved) {
|
||||||
default_reg_popup.open = true;
|
default_reg_popup.open = true;
|
||||||
const auto pos = GImGui->LastItemData.Rect.Max + ImVec2(5.0f, 0.0f);
|
default_reg_popup.SetPos(pos, true);
|
||||||
SetNextWindowPos(pos, ImGuiCond_Always);
|
|
||||||
default_reg_popup.Draw(true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -158,7 +159,6 @@ void RegView::DrawRegs() {
|
|||||||
if (regs.depth_buffer.Address() == 0 || !regs.depth_control.depth_enable) {
|
if (regs.depth_buffer.Address() == 0 || !regs.depth_control.depth_enable) {
|
||||||
TextUnformatted("N/A");
|
TextUnformatted("N/A");
|
||||||
} else {
|
} else {
|
||||||
constexpr auto depth_id = 0xF3;
|
|
||||||
const char* text = last_selected_cb == depth_id && default_reg_popup.open ? "x" : "->";
|
const char* text = last_selected_cb == depth_id && default_reg_popup.open ? "x" : "->";
|
||||||
if (SmallButton(text)) {
|
if (SmallButton(text)) {
|
||||||
open_new_popup(depth_id, regs.depth_buffer, regs.depth_control);
|
open_new_popup(depth_id, regs.depth_buffer, regs.depth_control);
|
||||||
@ -176,7 +176,7 @@ RegView::RegView() {
|
|||||||
char name[128];
|
char name[128];
|
||||||
snprintf(name, sizeof(name), "###reg_dump_%d", id);
|
snprintf(name, sizeof(name), "###reg_dump_%d", id);
|
||||||
SetNextWindowPos({400.0f, 200.0f});
|
SetNextWindowPos({400.0f, 200.0f});
|
||||||
SetNextWindowSize({290.0f, 425.0f});
|
SetNextWindowSize({290.0f, 435.0f});
|
||||||
ImGuiID root_dock_id;
|
ImGuiID root_dock_id;
|
||||||
Begin(name);
|
Begin(name);
|
||||||
{
|
{
|
||||||
@ -204,25 +204,58 @@ RegView::RegView() {
|
|||||||
DockBuilderFinish(root_dock_id);
|
DockBuilderFinish(root_dock_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegView::SetData(DebugStateType::RegDump data, const std::string& base_title, u32 batch_id) {
|
void RegView::SetData(DebugStateType::RegDump _data, const std::string& base_title, u32 batch_id) {
|
||||||
this->data = std::move(data);
|
this->data = std::move(_data);
|
||||||
this->batch_id = batch_id;
|
this->batch_id = batch_id;
|
||||||
this->title = fmt::format("{}/Batch {}", base_title, batch_id);
|
this->title = fmt::format("{}/Batch {}", base_title, batch_id);
|
||||||
// clear cache
|
// clear cache
|
||||||
selected_shader = -1;
|
|
||||||
shader_decomp.clear();
|
shader_decomp.clear();
|
||||||
|
const auto& regs = data.regs;
|
||||||
|
if (selected_shader >= 0 && !regs.stage_enable.IsStageEnabled(selected_shader)) {
|
||||||
|
selected_shader = -1;
|
||||||
|
}
|
||||||
|
if (default_reg_popup.open) {
|
||||||
default_reg_popup.open = false;
|
default_reg_popup.open = false;
|
||||||
|
if (last_selected_cb == depth_id) {
|
||||||
|
const auto& has_depth =
|
||||||
|
regs.depth_buffer.Address() != 0 && regs.depth_control.depth_enable;
|
||||||
|
if (has_depth) {
|
||||||
|
default_reg_popup.SetData(title, regs.depth_buffer, regs.depth_control);
|
||||||
|
default_reg_popup.open = true;
|
||||||
|
}
|
||||||
|
} else if (last_selected_cb >= 0 && last_selected_cb < AmdGpu::Liverpool::NumColorBuffers) {
|
||||||
|
const auto& buffer = regs.color_buffers[last_selected_cb];
|
||||||
|
const bool has_cb = buffer && regs.color_target_mask.GetMask(last_selected_cb);
|
||||||
|
if (has_cb) {
|
||||||
|
default_reg_popup.SetData(title, buffer, last_selected_cb);
|
||||||
|
default_reg_popup.open = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
extra_reg_popup.clear();
|
extra_reg_popup.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RegView::SetPos(ImVec2 pos) {
|
||||||
|
char name[128];
|
||||||
|
snprintf(name, sizeof(name), "%s###reg_dump_%d", title.c_str(), id);
|
||||||
|
Begin(name, &open, ImGuiWindowFlags_MenuBar);
|
||||||
|
SetWindowPos(pos);
|
||||||
|
KeepWindowInside();
|
||||||
|
last_pos = GetWindowPos();
|
||||||
|
moved = false;
|
||||||
|
End();
|
||||||
|
}
|
||||||
|
|
||||||
void RegView::Draw() {
|
void RegView::Draw() {
|
||||||
char name[128];
|
char name[128];
|
||||||
snprintf(name, sizeof(name), "%s###reg_dump_%d", title.c_str(), id);
|
snprintf(name, sizeof(name), "%s###reg_dump_%d", title.c_str(), id);
|
||||||
|
|
||||||
if (Begin(name, &open, ImGuiWindowFlags_MenuBar)) {
|
if (Begin(name, &open, ImGuiWindowFlags_MenuBar)) {
|
||||||
const char* names[] = {"vs", "ps", "gs", "es", "hs", "ls"};
|
if (GetWindowPos() != last_pos) {
|
||||||
|
moved = true;
|
||||||
|
}
|
||||||
|
|
||||||
KeepWindowInside();
|
const char* names[] = {"vs", "ps", "gs", "es", "hs", "ls"};
|
||||||
|
|
||||||
if (BeginMenuBar()) {
|
if (BeginMenuBar()) {
|
||||||
if (BeginMenu("Windows")) {
|
if (BeginMenu("Windows")) {
|
||||||
|
@ -21,6 +21,7 @@ class RegView {
|
|||||||
std::string title;
|
std::string title;
|
||||||
DebugStateType::RegDump data;
|
DebugStateType::RegDump data;
|
||||||
u32 batch_id{~0u};
|
u32 batch_id{~0u};
|
||||||
|
ImVec2 last_pos;
|
||||||
|
|
||||||
std::unordered_map<int, ShaderCache> shader_decomp;
|
std::unordered_map<int, ShaderCache> shader_decomp;
|
||||||
int selected_shader{-1};
|
int selected_shader{-1};
|
||||||
@ -40,11 +41,14 @@ class RegView {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
bool open = false;
|
bool open = false;
|
||||||
|
bool moved = false;
|
||||||
|
|
||||||
RegView();
|
RegView();
|
||||||
|
|
||||||
void SetData(DebugStateType::RegDump data, const std::string& base_title, u32 batch_id);
|
void SetData(DebugStateType::RegDump data, const std::string& base_title, u32 batch_id);
|
||||||
|
|
||||||
|
void SetPos(ImVec2 pos);
|
||||||
|
|
||||||
void Draw();
|
void Draw();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user