mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-06-16 07:33:14 +00:00
Devtools - Inspect regs/User data/Shader disassembly (#1358)
* devtools: pm4 - show markers * SaveDataDialogLib: fix compile with mingw * devtools: pm4 - show program state * devtools: pm4 - show program disassembly * devtools: pm4 - show frame regs * devtools: pm4 - show color buffer info as popup add ux improvements for open new windows with shift+click better window titles * imgui: skip all textures to avoid hanging with crash diagnostic enabled not sure why this happens :c * devtools: pm4 - show reg depth buffer
This commit is contained in:
parent
8776eba8c8
commit
cf2e617f08
27 changed files with 4215 additions and 287 deletions
|
@ -10,6 +10,7 @@
|
|||
#include "imgui/imgui_std.h"
|
||||
#include "imgui_internal.h"
|
||||
#include "layer.h"
|
||||
#include "options.h"
|
||||
#include "widget/frame_dump.h"
|
||||
#include "widget/frame_graph.h"
|
||||
|
||||
|
@ -18,10 +19,9 @@ using namespace Core::Devtools;
|
|||
using L = Core::Devtools::Layer;
|
||||
|
||||
static bool show_simple_fps = false;
|
||||
|
||||
static float fps_scale = 1.0f;
|
||||
|
||||
static bool show_advanced_debug = false;
|
||||
|
||||
static int dump_frame_count = 1;
|
||||
|
||||
static Widget::FrameGraph frame_graph;
|
||||
|
@ -29,12 +29,16 @@ static std::vector<Widget::FrameDumpViewer> frame_viewers;
|
|||
|
||||
static float debug_popup_timing = 3.0f;
|
||||
|
||||
static bool just_opened_options = false;
|
||||
|
||||
void L::DrawMenuBar() {
|
||||
const auto& ctx = *GImGui;
|
||||
const auto& io = ctx.IO;
|
||||
|
||||
auto isSystemPaused = DebugState.IsGuestThreadsPaused();
|
||||
|
||||
bool open_popup_options = false;
|
||||
|
||||
if (BeginMainMenuBar()) {
|
||||
if (BeginMenu("Options")) {
|
||||
if (MenuItemEx("Emulator Paused", nullptr, nullptr, isSystemPaused)) {
|
||||
|
@ -55,6 +59,7 @@ void L::DrawMenuBar() {
|
|||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
open_popup_options = MenuItem("Options");
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
EndMainMenuBar();
|
||||
|
@ -74,6 +79,11 @@ void L::DrawMenuBar() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (open_popup_options) {
|
||||
OpenPopup("GPU Tools Options");
|
||||
just_opened_options = true;
|
||||
}
|
||||
}
|
||||
|
||||
void L::DrawAdvanced() {
|
||||
|
@ -91,13 +101,19 @@ void L::DrawAdvanced() {
|
|||
->AddText({10.0f, io.DisplaySize.y - 40.0f}, IM_COL32_WHITE, "Emulator paused");
|
||||
}
|
||||
|
||||
if (DebugState.should_show_frame_dump) {
|
||||
if (DebugState.should_show_frame_dump && DebugState.waiting_reg_dumps.empty()) {
|
||||
DebugState.should_show_frame_dump = false;
|
||||
std::unique_lock lock{DebugState.frame_dump_list_mutex};
|
||||
while (!DebugState.frame_dump_list.empty()) {
|
||||
auto frame_dump = std::move(DebugState.frame_dump_list.back());
|
||||
DebugState.frame_dump_list.pop_back();
|
||||
const auto& frame_dump = DebugState.frame_dump_list.back();
|
||||
frame_viewers.emplace_back(frame_dump);
|
||||
DebugState.frame_dump_list.pop_back();
|
||||
}
|
||||
static bool first_time = true;
|
||||
if (first_time) {
|
||||
first_time = false;
|
||||
DebugState.ShowDebugMessage("Tip: You can shift+click any\n"
|
||||
"popup to open a new window");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,6 +149,30 @@ void L::DrawAdvanced() {
|
|||
debug_popup_timing = 3.0f;
|
||||
}
|
||||
}
|
||||
|
||||
bool close_popup_options = true;
|
||||
if (BeginPopupModal("GPU Tools Options", &close_popup_options,
|
||||
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings)) {
|
||||
static char disassembly_cli[512];
|
||||
|
||||
if (just_opened_options) {
|
||||
just_opened_options = false;
|
||||
auto s = Options.disassembly_cli.copy(disassembly_cli, sizeof(disassembly_cli) - 1);
|
||||
disassembly_cli[s] = '\0';
|
||||
}
|
||||
|
||||
InputText("Shader disassembler: ", disassembly_cli, sizeof(disassembly_cli));
|
||||
if (IsItemHovered()) {
|
||||
SetTooltip(R"(Command to disassemble shaders. Example "dis.exe" --raw "{src}")");
|
||||
}
|
||||
|
||||
if (Button("Save")) {
|
||||
Options.disassembly_cli = disassembly_cli;
|
||||
SaveIniSettingsToDisk(io.IniFilename);
|
||||
CloseCurrentPopup();
|
||||
}
|
||||
EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
void L::DrawSimple() {
|
||||
|
@ -140,26 +180,54 @@ void L::DrawSimple() {
|
|||
Text("Frame time: %.3f ms (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate);
|
||||
}
|
||||
|
||||
static void LoadSettings(const char* line) {
|
||||
int i;
|
||||
float f;
|
||||
if (sscanf(line, "fps_scale=%f", &f) == 1) {
|
||||
fps_scale = f;
|
||||
return;
|
||||
}
|
||||
if (sscanf(line, "show_advanced_debug=%d", &i) == 1) {
|
||||
show_advanced_debug = i != 0;
|
||||
return;
|
||||
}
|
||||
if (sscanf(line, "show_frame_graph=%d", &i) == 1) {
|
||||
frame_graph.is_open = i != 0;
|
||||
return;
|
||||
}
|
||||
if (sscanf(line, "dump_frame_count=%d", &i) == 1) {
|
||||
dump_frame_count = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void L::SetupSettings() {
|
||||
frame_graph.is_open = true;
|
||||
|
||||
using SettingLoader = void (*)(const char*);
|
||||
|
||||
ImGuiSettingsHandler handler{};
|
||||
handler.TypeName = "DevtoolsLayer";
|
||||
handler.TypeHash = ImHashStr(handler.TypeName);
|
||||
handler.ReadOpenFn = [](ImGuiContext*, ImGuiSettingsHandler*, const char* name) {
|
||||
return std::string_view("Data") == name ? (void*)1 : nullptr;
|
||||
if (std::string_view("Data") == name) {
|
||||
static_assert(std::is_same_v<decltype(&LoadSettings), SettingLoader>);
|
||||
return (void*)&LoadSettings;
|
||||
}
|
||||
if (std::string_view("CmdList") == name) {
|
||||
static_assert(
|
||||
std::is_same_v<decltype(&Widget::CmdListViewer::LoadConfig), SettingLoader>);
|
||||
return (void*)&Widget::CmdListViewer::LoadConfig;
|
||||
}
|
||||
if (std::string_view("Options") == name) {
|
||||
static_assert(std::is_same_v<decltype(&LoadOptionsConfig), SettingLoader>);
|
||||
return (void*)&LoadOptionsConfig;
|
||||
}
|
||||
return (void*)nullptr;
|
||||
};
|
||||
handler.ReadLineFn = [](ImGuiContext*, ImGuiSettingsHandler*, void*, const char* line) {
|
||||
int v;
|
||||
float f;
|
||||
if (sscanf(line, "fps_scale=%f", &f) == 1) {
|
||||
fps_scale = f;
|
||||
} else if (sscanf(line, "show_advanced_debug=%d", &v) == 1) {
|
||||
show_advanced_debug = v != 0;
|
||||
} else if (sscanf(line, "show_frame_graph=%d", &v) == 1) {
|
||||
frame_graph.is_open = v != 0;
|
||||
} else if (sscanf(line, "dump_frame_count=%d", &v) == 1) {
|
||||
dump_frame_count = v;
|
||||
handler.ReadLineFn = [](ImGuiContext*, ImGuiSettingsHandler*, void* handle, const char* line) {
|
||||
if (handle != nullptr) {
|
||||
reinterpret_cast<SettingLoader>(handle)(line);
|
||||
}
|
||||
};
|
||||
handler.WriteAllFn = [](ImGuiContext*, ImGuiSettingsHandler* handler, ImGuiTextBuffer* buf) {
|
||||
|
@ -169,12 +237,19 @@ void L::SetupSettings() {
|
|||
buf->appendf("show_frame_graph=%d\n", frame_graph.is_open);
|
||||
buf->appendf("dump_frame_count=%d\n", dump_frame_count);
|
||||
buf->append("\n");
|
||||
buf->appendf("[%s][CmdList]\n", handler->TypeName);
|
||||
Widget::CmdListViewer::SerializeConfig(buf);
|
||||
buf->append("\n");
|
||||
buf->appendf("[%s][Options]\n", handler->TypeName);
|
||||
SerializeOptionsConfig(buf);
|
||||
buf->append("\n");
|
||||
};
|
||||
AddSettingsHandler(&handler);
|
||||
|
||||
const ImGuiID dock_id = ImHashStr("FrameDumpDock");
|
||||
DockBuilderAddNode(dock_id, 0);
|
||||
DockBuilderSetNodePos(dock_id, ImVec2{50.0, 50.0});
|
||||
DockBuilderSetNodePos(dock_id, ImVec2{450.0, 150.0});
|
||||
DockBuilderSetNodeSize(dock_id, ImVec2{400.0, 500.0});
|
||||
DockBuilderFinish(dock_id);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue