mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-06-05 18:23:16 +00:00
Devtools: PM4 Explorer (#1094)
* Devtools: Pause system * Devtools: pm4 viewer - new menu bar - refactored video_info layer - dump & inspect pm4 packets - removed dumpPM4 config - renamed System to DebugState - add docking space - simple video info constrained to window size * Devtools: pm4 viewer - add combo to select the queue * Devtools: pm4 viewer - add hex editor * Devtools: pm4 viewer - dump current cmd * add monospaced font to devtools * Devtools: pm4 viewer - use spec op name avoid some allocations
This commit is contained in:
parent
009f956d8d
commit
af398e3684
46 changed files with 19323 additions and 242 deletions
|
@ -10,6 +10,9 @@
|
|||
|
||||
#define IM_COL32_GRAY(x) IM_COL32(x, x, x, 0xFF)
|
||||
|
||||
#define IMGUI_FONT_TEXT 0
|
||||
#define IMGUI_FONT_MONO 1
|
||||
|
||||
namespace ImGui {
|
||||
|
||||
namespace Easing {
|
||||
|
@ -27,6 +30,20 @@ inline void CentralizeWindow() {
|
|||
SetNextWindowPos(display_size / 2.0f, ImGuiCond_Always, {0.5f});
|
||||
}
|
||||
|
||||
inline void KeepWindowInside(ImVec2 display_size = GetIO().DisplaySize) {
|
||||
const auto cur_pos = GetWindowPos();
|
||||
if (cur_pos.x < 0.0f || cur_pos.y < 0.0f) {
|
||||
SetWindowPos(ImMax(cur_pos, ImVec2(0.0f, 0.0f)));
|
||||
return;
|
||||
}
|
||||
const auto cur_size = GetWindowSize();
|
||||
const auto bottom_right = cur_pos + cur_size;
|
||||
if (bottom_right.x > display_size.x || bottom_right.y > display_size.y) {
|
||||
const auto max_pos = display_size - cur_size;
|
||||
SetWindowPos(ImMin(cur_pos, max_pos));
|
||||
}
|
||||
}
|
||||
|
||||
inline void KeepNavHighlight() {
|
||||
GetCurrentContext()->NavDisableHighlight = false;
|
||||
}
|
||||
|
|
|
@ -1,121 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
#include "common/config.h"
|
||||
#include "common/types.h"
|
||||
#include "imgui_internal.h"
|
||||
#include "video_info.h"
|
||||
|
||||
using namespace ImGui;
|
||||
|
||||
struct FrameInfo {
|
||||
u32 num;
|
||||
float delta;
|
||||
};
|
||||
|
||||
static bool show = false;
|
||||
static bool show_advanced = false;
|
||||
|
||||
static u32 current_frame = 0;
|
||||
constexpr float TARGET_FPS = 60.0f;
|
||||
constexpr u32 FRAME_BUFFER_SIZE = 1024;
|
||||
constexpr float BAR_WIDTH_MULT = 1.4f;
|
||||
constexpr float BAR_HEIGHT_MULT = 1.25f;
|
||||
constexpr float FRAME_GRAPH_PADDING_Y = 3.0f;
|
||||
static std::array<FrameInfo, FRAME_BUFFER_SIZE> frame_list;
|
||||
static float frame_graph_height = 50.0f;
|
||||
|
||||
static void DrawSimple() {
|
||||
const auto io = GetIO();
|
||||
Text("FPS: %.1f (%.3f ms)", io.Framerate, 1000.0f / io.Framerate);
|
||||
}
|
||||
|
||||
static void DrawAdvanced() {
|
||||
const auto& ctx = *GetCurrentContext();
|
||||
const auto& io = ctx.IO;
|
||||
const auto& window = *ctx.CurrentWindow;
|
||||
auto& draw_list = *window.DrawList;
|
||||
|
||||
Text("Frame time: %.3f ms (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate);
|
||||
|
||||
SeparatorText("Frame graph");
|
||||
const float full_width = GetContentRegionAvail().x;
|
||||
{ // Frame graph - inspired by
|
||||
// https://asawicki.info/news_1758_an_idea_for_visualization_of_frame_times
|
||||
auto pos = GetCursorScreenPos();
|
||||
const ImVec2 size{full_width, frame_graph_height + FRAME_GRAPH_PADDING_Y * 2.0f};
|
||||
ItemSize(size);
|
||||
if (!ItemAdd({pos, pos + size}, GetID("FrameGraph"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
float target_dt = 1.0f / (TARGET_FPS * (float)Config::vblankDiv());
|
||||
float cur_pos_x = pos.x + full_width;
|
||||
pos.y += FRAME_GRAPH_PADDING_Y;
|
||||
const float final_pos_y = pos.y + frame_graph_height;
|
||||
|
||||
draw_list.AddRectFilled({pos.x, pos.y - FRAME_GRAPH_PADDING_Y},
|
||||
{pos.x + full_width, final_pos_y + FRAME_GRAPH_PADDING_Y},
|
||||
IM_COL32(0x33, 0x33, 0x33, 0xFF));
|
||||
draw_list.PushClipRect({pos.x, pos.y}, {pos.x + full_width, final_pos_y}, true);
|
||||
for (u32 i = 0; i < FRAME_BUFFER_SIZE; ++i) {
|
||||
const auto& frame_info = frame_list[(current_frame - i) % FRAME_BUFFER_SIZE];
|
||||
const float dt_factor = target_dt / frame_info.delta;
|
||||
|
||||
const float width = std::ceil(BAR_WIDTH_MULT / dt_factor);
|
||||
const float height =
|
||||
std::min(std::log2(BAR_HEIGHT_MULT / dt_factor) / 3.0f, 1.0f) * frame_graph_height;
|
||||
|
||||
ImU32 color;
|
||||
if (dt_factor >= 0.95f) { // BLUE
|
||||
color = IM_COL32(0x33, 0x33, 0xFF, 0xFF);
|
||||
} else if (dt_factor >= 0.5f) { // GREEN <> YELLOW
|
||||
float t = 1.0f - (dt_factor - 0.5f) * 2.0f;
|
||||
int r = (int)(0xFF * t);
|
||||
color = IM_COL32(r, 0xFF, 0, 0xFF);
|
||||
} else { // YELLOW <> RED
|
||||
float t = dt_factor * 2.0f;
|
||||
int g = (int)(0xFF * t);
|
||||
color = IM_COL32(0xFF, g, 0, 0xFF);
|
||||
}
|
||||
draw_list.AddRectFilled({cur_pos_x - width, final_pos_y - height},
|
||||
{cur_pos_x, final_pos_y}, color);
|
||||
cur_pos_x -= width;
|
||||
if (cur_pos_x < width) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
draw_list.PopClipRect();
|
||||
}
|
||||
}
|
||||
|
||||
void Layers::VideoInfo::Draw() {
|
||||
const auto io = GetIO();
|
||||
|
||||
const FrameInfo frame_info{
|
||||
.num = ++current_frame,
|
||||
.delta = io.DeltaTime,
|
||||
};
|
||||
frame_list[current_frame % FRAME_BUFFER_SIZE] = frame_info;
|
||||
|
||||
if (IsKeyPressed(ImGuiKey_F10, false)) {
|
||||
const bool changed_ctrl = io.KeyCtrl != show_advanced;
|
||||
show_advanced = io.KeyCtrl;
|
||||
show = changed_ctrl || !show;
|
||||
}
|
||||
|
||||
if (show) {
|
||||
if (show_advanced) {
|
||||
if (Begin("Video Debug Info", nullptr, ImGuiWindowFlags_NoDecoration)) {
|
||||
DrawAdvanced();
|
||||
}
|
||||
} else {
|
||||
if (Begin("Video Info", nullptr, ImGuiWindowFlags_NoDecoration)) {
|
||||
DrawSimple();
|
||||
}
|
||||
}
|
||||
End();
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "imgui/imgui_layer.h"
|
||||
|
||||
namespace Vulkan {
|
||||
class RendererVulkan;
|
||||
}
|
||||
namespace ImGui::Layers {
|
||||
|
||||
class VideoInfo : public Layer {
|
||||
::Vulkan::RendererVulkan* renderer{};
|
||||
|
||||
public:
|
||||
explicit VideoInfo(::Vulkan::RendererVulkan* renderer) : renderer(renderer) {}
|
||||
|
||||
void Draw() override;
|
||||
};
|
||||
|
||||
} // namespace ImGui::Layers
|
|
@ -7,6 +7,7 @@ add_executable(Dear_ImGui_FontEmbed ${CMAKE_SOURCE_DIR}/externals/dear_imgui/mis
|
|||
|
||||
set(FONT_LIST
|
||||
NotoSansJP-Regular.ttf
|
||||
ProggyVector-Regular.ttf
|
||||
)
|
||||
|
||||
set(OutputList "")
|
||||
|
|
BIN
src/imgui/renderer/fonts/ProggyVector-Regular.ttf
Normal file
BIN
src/imgui/renderer/fonts/ProggyVector-Regular.ttf
Normal file
Binary file not shown.
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "common/config.h"
|
||||
#include "common/path_util.h"
|
||||
#include "core/devtools/layer.h"
|
||||
#include "imgui/imgui_layer.h"
|
||||
#include "imgui_core.h"
|
||||
#include "imgui_impl_sdl3.h"
|
||||
|
@ -16,6 +17,7 @@
|
|||
#include "video_core/renderer_vulkan/renderer_vulkan.h"
|
||||
|
||||
#include "imgui_fonts/notosansjp_regular.ttf.g.cpp"
|
||||
#include "imgui_fonts/proggyvector_regular.ttf.g.cpp"
|
||||
|
||||
static void CheckVkResult(const vk::Result err) {
|
||||
LOG_ERROR(ImGui, "Vulkan error {}", vk::to_string(err));
|
||||
|
@ -74,12 +76,16 @@ void Initialize(const ::Vulkan::Instance& instance, const Frontend::WindowSDL& w
|
|||
ImFontConfig font_cfg{};
|
||||
font_cfg.OversampleH = 2;
|
||||
font_cfg.OversampleV = 1;
|
||||
io.Fonts->AddFontFromMemoryCompressedTTF(imgui_font_notosansjp_regular_compressed_data,
|
||||
imgui_font_notosansjp_regular_compressed_size, 16.0f,
|
||||
&font_cfg, ranges.Data);
|
||||
io.FontDefault = io.Fonts->AddFontFromMemoryCompressedTTF(
|
||||
imgui_font_notosansjp_regular_compressed_data,
|
||||
imgui_font_notosansjp_regular_compressed_size, 16.0f, &font_cfg, ranges.Data);
|
||||
io.Fonts->AddFontFromMemoryCompressedTTF(imgui_font_proggyvector_regular_compressed_data,
|
||||
imgui_font_proggyvector_regular_compressed_size,
|
||||
16.0f);
|
||||
|
||||
StyleColorsDark();
|
||||
|
||||
::Core::Devtools::Layer::SetupSettings();
|
||||
Sdl::Init(window.GetSdlWindow());
|
||||
|
||||
const Vulkan::InitInfo vk_info{
|
||||
|
@ -166,6 +172,8 @@ void NewFrame() {
|
|||
Sdl::NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
DockSpaceOverViewport(0, GetMainViewport(), ImGuiDockNodeFlags_PassthruCentralNode);
|
||||
|
||||
for (auto* layer : layers) {
|
||||
layer->Draw();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue