mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-26 23:10:38 +00:00
Ge Debugger: Add a framebuffer listing, along with some plumbing
This commit is contained in:
parent
21ffc37ebd
commit
d068f79f78
@ -457,6 +457,8 @@ public:
|
||||
int MultiSampleLevel() const { return multiSampleLevel_; }
|
||||
|
||||
virtual void UpdateTag(const char *tag) {}
|
||||
virtual const char *Tag() { return "(no name)"; }
|
||||
|
||||
protected:
|
||||
int width_ = -1, height_ = -1, layers_ = 1, multiSampleLevel_ = 0;
|
||||
};
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include <sstream>
|
||||
#include <cmath>
|
||||
|
||||
#include "ext/imgui/imgui.h"
|
||||
|
||||
#include "Common/GPU/thin3d.h"
|
||||
#include "Common/GPU/OpenGL/GLFeatures.h"
|
||||
#include "Common/Data/Collections/TinySet.h"
|
||||
@ -3661,3 +3663,44 @@ static void ApplyKillzoneFramebufferSplit(FramebufferHeuristicParams *params, in
|
||||
*drawing_width = 480;
|
||||
}
|
||||
}
|
||||
|
||||
void FramebufferManagerCommon::DrawImGuiDebug(int &selected) const {
|
||||
ImGui::BeginTable("framebuffers", 4);
|
||||
ImGui::TableSetupColumn("Tag");
|
||||
ImGui::TableSetupColumn("Color Addr");
|
||||
ImGui::TableSetupColumn("Depth Addr");
|
||||
ImGui::TableSetupColumn("Size");
|
||||
|
||||
ImGui::TableHeadersRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
|
||||
for (int i = 0; i < (int)vfbs_.size(); i++) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
auto &vfb = vfbs_[i];
|
||||
|
||||
const char *tag = vfb->fbo ? vfb->fbo->Tag() : "(no tag)";
|
||||
|
||||
ImGui::PushID(i);
|
||||
if (ImGui::Selectable(tag, selected == i, ImGuiSelectableFlags_AllowDoubleClick | ImGuiSelectableFlags_SpanAllColumns)) {
|
||||
selected = i;
|
||||
}
|
||||
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
|
||||
selected = i;
|
||||
ImGui::OpenPopup("framebufferPopup");
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%08x", vfb->fb_address);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%08x", vfb->z_address);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%dx%d", vfb->width, vfb->height);
|
||||
if (ImGui::BeginPopup("framebufferPopup")) {
|
||||
ImGui::Text("Framebuffer: %s", tag);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
@ -488,6 +488,8 @@ public:
|
||||
|
||||
bool PresentedThisFrame() const;
|
||||
|
||||
void DrawImGuiDebug(int &selected) const;
|
||||
|
||||
protected:
|
||||
virtual void ReadbackFramebuffer(VirtualFramebuffer *vfb, int x, int y, int w, int h, RasterChannel channel, Draw::ReadbackMode mode);
|
||||
// Used for when a shader is required, such as GLES.
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include "GPU/GPU.h"
|
||||
#include "GPU/GPUInterface.h"
|
||||
|
||||
class FramebufferManagerCommon;
|
||||
|
||||
struct GPUDebugOp {
|
||||
u32 pc;
|
||||
u8 cmd;
|
||||
@ -218,6 +220,9 @@ public:
|
||||
|
||||
virtual uint32_t SetAddrTranslation(uint32_t value) = 0;
|
||||
virtual uint32_t GetAddrTranslation() = 0;
|
||||
|
||||
// TODO: Make a proper debug interface instead of accessing directly?
|
||||
virtual FramebufferManagerCommon *GetFramebufferManagerCommon() = 0;
|
||||
|
||||
virtual bool GetCurrentSimpleVertices(int count, std::vector<GPUDebugVertex> &vertices, std::vector<u16> &indices) {
|
||||
return false;
|
||||
|
@ -181,6 +181,10 @@ public:
|
||||
bool GetCurrentDisplayList(DisplayList &list) override;
|
||||
bool GetCurrentSimpleVertices(int count, std::vector<GPUDebugVertex> &vertices, std::vector<u16> &indices) override;
|
||||
|
||||
FramebufferManagerCommon *GetFramebufferManagerCommon() override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<std::string> DebugGetShaderIDs(DebugShaderType shader) override { return std::vector<std::string>(); };
|
||||
std::string DebugGetShaderString(std::string id, DebugShaderType shader, DebugShaderStringType stringType) override {
|
||||
return "N/A";
|
||||
|
@ -28,6 +28,10 @@ public:
|
||||
bool GetCurrentTexture(GPUDebugBuffer &buffer, int level, bool *isFramebuffer) override;
|
||||
bool GetCurrentClut(GPUDebugBuffer &buffer) override;
|
||||
|
||||
FramebufferManagerCommon *GetFramebufferManagerCommon() override {
|
||||
return framebufferManager_;
|
||||
}
|
||||
|
||||
// Using string because it's generic - makes no assumptions on the size of the shader IDs of this backend.
|
||||
std::vector<std::string> DebugGetShaderIDs(DebugShaderType shader) override;
|
||||
std::string DebugGetShaderString(std::string id, DebugShaderType shader, DebugShaderStringType stringType) override;
|
||||
|
@ -1656,7 +1656,7 @@ void EmuScreen::renderImDebugger() {
|
||||
ImGui_ImplThin3d_NewFrame(draw, ui_draw2d.GetDrawMatrix());
|
||||
|
||||
ImGui::NewFrame();
|
||||
imDebugger_->Frame(currentDebugMIPS);
|
||||
imDebugger_->Frame(currentDebugMIPS, gpuDebug);
|
||||
|
||||
ImGui::Render();
|
||||
ImGui_ImplThin3d_RenderDrawData(ImGui::GetDrawData(), draw);
|
||||
|
@ -26,7 +26,11 @@
|
||||
// Callstack window
|
||||
#include "Core/MIPS/MIPSStackWalk.h"
|
||||
|
||||
// GPU things
|
||||
#include "GPU/Common/GPUDebugInterface.h"
|
||||
|
||||
#include "UI/ImDebugger/ImDebugger.h"
|
||||
#include "UI/ImDebugger/ImGe.h"
|
||||
|
||||
void DrawRegisterView(MIPSDebugInterface *mipsDebug, bool *open) {
|
||||
if (!ImGui::Begin("Registers", open)) {
|
||||
@ -332,7 +336,7 @@ void DrawHLEModules(ImConfig &config) {
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void ImDebugger::Frame(MIPSDebugInterface *mipsDebug) {
|
||||
void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebug) {
|
||||
// Snapshot the coreState to avoid inconsistency.
|
||||
const CoreState coreState = ::coreState;
|
||||
|
||||
@ -370,14 +374,23 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug) {
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if (ImGui::BeginMenu("Window")) {
|
||||
ImGui::Checkbox("Dear ImGUI Demo", &cfg_.demoOpen);
|
||||
if (ImGui::BeginMenu("CPU")) {
|
||||
ImGui::Checkbox("CPU debugger", &cfg_.disasmOpen);
|
||||
ImGui::Checkbox("Registers", &cfg_.regsOpen);
|
||||
ImGui::Checkbox("Callstacks", &cfg_.callstackOpen);
|
||||
ImGui::Checkbox("HLE Modules", &cfg_.modulesOpen);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if (ImGui::BeginMenu("OS HLE")) {
|
||||
ImGui::Checkbox("HLE Threads", &cfg_.threadsOpen);
|
||||
ImGui::Checkbox("HLE Modules", &cfg_.modulesOpen);
|
||||
ImGui::Checkbox("sceAtrac", &cfg_.atracOpen);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if (ImGui::BeginMenu("Ge (GPU)")) {
|
||||
ImGui::Checkbox("Framebuffers", &cfg_.framebuffersOpen);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if (ImGui::BeginMenu("Tools")) {
|
||||
ImGui::Checkbox("Struct viewer", &cfg_.structViewerOpen);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
@ -385,6 +398,7 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug) {
|
||||
if (ImGui::MenuItem("Close Debugger")) {
|
||||
g_Config.bShowImDebugger = false;
|
||||
}
|
||||
ImGui::Checkbox("Dear ImGUI Demo", &cfg_.demoOpen);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMainMenuBar();
|
||||
@ -422,6 +436,10 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug) {
|
||||
DrawHLEModules(cfg_);
|
||||
}
|
||||
|
||||
if (cfg_.framebuffersOpen) {
|
||||
DrawFramebuffersWindow(cfg_, gpuDebug->GetFramebufferManagerCommon());
|
||||
}
|
||||
|
||||
if (cfg_.structViewerOpen) {
|
||||
structViewer_.Draw(mipsDebug, &cfg_.structViewerOpen);
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include "UI/ImDebugger/ImDisasmView.h"
|
||||
#include "UI/ImDebugger/ImStructViewer.h"
|
||||
#include "UI/ImDebugger/ImGe.h"
|
||||
|
||||
// This is the main state container of the whole Dear ImGUI-based in-game cross-platform debugger.
|
||||
//
|
||||
@ -22,7 +23,7 @@
|
||||
// * If windows/objects need state, prefix the class name with Im and just store straight in parent struct
|
||||
|
||||
class MIPSDebugInterface;
|
||||
|
||||
class GPUDebugInterface;
|
||||
|
||||
// Corresponds to the CDisasm dialog
|
||||
class ImDisasmWindow {
|
||||
@ -59,6 +60,7 @@ struct ImConfig {
|
||||
bool hleModulesOpen = false;
|
||||
bool atracOpen = true;
|
||||
bool structViewerOpen = false;
|
||||
bool framebuffersOpen = false;
|
||||
|
||||
// HLE explorer settings
|
||||
// bool filterByUsed = true;
|
||||
@ -66,10 +68,11 @@ struct ImConfig {
|
||||
// Various selections
|
||||
int selectedModule = 0;
|
||||
int selectedThread = 0;
|
||||
int selectedFramebuffer = -1;
|
||||
};
|
||||
|
||||
struct ImDebugger {
|
||||
void Frame(MIPSDebugInterface *mipsDebug);
|
||||
void Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebug);
|
||||
|
||||
ImDisasmWindow disasm_;
|
||||
ImLuaConsole luaConsole_;
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "ext/imgui/imgui_internal.h"
|
||||
|
||||
#include "Common/StringUtils.h"
|
||||
#include "Common/Log.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/Debugger/DebugInterface.h"
|
||||
#include "Core/Debugger/DisassemblyManager.h"
|
||||
@ -417,11 +418,11 @@ void ImDisasmView::Draw(ImDrawList *drawList) {
|
||||
line.params += line.info.conditionMet ? " ; true" : " ; false";
|
||||
}
|
||||
|
||||
drawArguments(drawList, rect, line, pixelPositions_.argumentsStart, rowY1 + 2, textColor, currentArguments);
|
||||
drawArguments(drawList, rect, line, pixelPositions_.argumentsStart, rowY1 + 2.f, textColor, currentArguments);
|
||||
|
||||
// The actual opcode.
|
||||
// Should be bold!
|
||||
drawList->AddText(ImVec2(rect.left + pixelPositions_.opcodeStart, rect.top + rowY1 + 2), textColor, line.name.c_str());
|
||||
drawList->AddText(ImVec2(rect.left + pixelPositions_.opcodeStart, rect.top + rowY1 + 2.f), textColor, line.name.c_str());
|
||||
|
||||
address += line.totalSize;
|
||||
}
|
||||
@ -707,7 +708,7 @@ void ImDisasmView::toggleBreakpoint(bool toggleEnabled) {
|
||||
}
|
||||
}
|
||||
|
||||
void ImDisasmView::onMouseDown(int x, int y, int button) {
|
||||
void ImDisasmView::onMouseDown(float x, float y, int button) {
|
||||
u32 newAddress = yToAddress(y);
|
||||
bool extend = ImGui::IsKeyDown(ImGuiKey_LeftShift);
|
||||
if (button == 1) {
|
||||
@ -722,6 +723,20 @@ void ImDisasmView::onMouseDown(int x, int y, int button) {
|
||||
setCurAddress(newAddress, extend);
|
||||
}
|
||||
|
||||
void ImDisasmView::onMouseMove(float x, float y, int button) {
|
||||
if ((button & 1) != 0) {
|
||||
setCurAddress(yToAddress(y), ImGui::IsKeyDown(ImGuiKey_LeftShift));
|
||||
}
|
||||
}
|
||||
|
||||
void ImDisasmView::onMouseUp(float x, float y, int button) {
|
||||
if (button == 1) {
|
||||
if (ImGui::IsKeyDown(ImGuiKey_LeftShift)) {
|
||||
setCurAddress(yToAddress(y), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ImDisasmView::CopyInstructions(u32 startAddr, u32 endAddr, CopyInstructionsMode mode) {
|
||||
_assert_msg_((startAddr & 3) == 0, "readMemory() can't handle unaligned reads");
|
||||
|
||||
@ -758,14 +773,6 @@ void ImDisasmView::NopInstructions(u32 selectRangeStart, u32 selectRangeEnd) {
|
||||
}
|
||||
}
|
||||
|
||||
void ImDisasmView::onMouseUp(int x, int y, int button) {
|
||||
if (button == 1) {
|
||||
if (ImGui::IsKeyDown(ImGuiKey_LeftShift)) {
|
||||
setCurAddress(yToAddress(y), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ImDisasmView::PopupMenu() {
|
||||
if (ImGui::BeginPopup("context")) {
|
||||
ImGui::Text("Address: %08x", curAddress_);
|
||||
@ -891,12 +898,6 @@ void ImDisasmView::PopupMenu() {
|
||||
}
|
||||
}
|
||||
|
||||
void ImDisasmView::onMouseMove(int x, int y, int button) {
|
||||
if ((button & 1) != 0) {
|
||||
setCurAddress(yToAddress(y), ImGui::IsKeyDown(ImGuiKey_LeftShift));
|
||||
}
|
||||
}
|
||||
|
||||
void ImDisasmView::updateStatusBarText() {
|
||||
auto memLock = Memory::Lock();
|
||||
if (!PSP_IsInited())
|
||||
@ -997,8 +998,8 @@ void ImDisasmView::updateStatusBarText() {
|
||||
}
|
||||
}
|
||||
|
||||
u32 ImDisasmView::yToAddress(int y) {
|
||||
int line = y / rowHeight_;
|
||||
u32 ImDisasmView::yToAddress(float y) {
|
||||
int line = (int)(y / rowHeight_);
|
||||
return manager.getNthNextAddress(windowStart_, line);
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include "ext/imgui/imgui.h"
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Log.h"
|
||||
|
||||
#include "Core/Debugger/DisassemblyManager.h"
|
||||
#include "Core/Debugger/DebugInterface.h"
|
||||
@ -31,16 +30,16 @@ public:
|
||||
|
||||
void onChar(int c);
|
||||
void onKeyDown(ImGuiKey key);
|
||||
void onMouseDown(int x, int y, int button);
|
||||
void onMouseUp(int x, int y, int button);
|
||||
void onMouseMove(int x, int y, int button);
|
||||
void onMouseDown(float x, float y, int button);
|
||||
void onMouseUp(float x, float y, int button);
|
||||
void onMouseMove(float x, float y, int button);
|
||||
void scrollAddressIntoView();
|
||||
bool curAddressIsVisible();
|
||||
void ScanVisibleFunctions();
|
||||
void clearFunctions() { manager.clear(); };
|
||||
|
||||
void getOpcodeText(u32 address, char* dest, int bufsize);
|
||||
u32 yToAddress(int y);
|
||||
u32 yToAddress(float y);
|
||||
|
||||
void setDebugger(DebugInterface *deb) {
|
||||
if (debugger != deb) {
|
||||
|
14
UI/ImDebugger/ImGe.cpp
Normal file
14
UI/ImDebugger/ImGe.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
#include "UI/ImDebugger/ImGe.h"
|
||||
#include "UI/ImDebugger/ImDebugger.h"
|
||||
#include "GPU/Common/FramebufferManagerCommon.h"
|
||||
|
||||
void DrawFramebuffersWindow(ImConfig &cfg, FramebufferManagerCommon *framebufferManager) {
|
||||
if (!ImGui::Begin("Framebuffers", &cfg.framebuffersOpen)) {
|
||||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
|
||||
framebufferManager->DrawImGuiDebug(cfg.selectedFramebuffer);
|
||||
|
||||
ImGui::End();
|
||||
}
|
9
UI/ImDebugger/ImGe.h
Normal file
9
UI/ImDebugger/ImGe.h
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
// GE-related windows of the ImDebugger
|
||||
|
||||
struct ImConfig;
|
||||
|
||||
class FramebufferManagerCommon;
|
||||
|
||||
void DrawFramebuffersWindow(ImConfig &cfg, FramebufferManagerCommon *framebufferManager);
|
@ -53,6 +53,7 @@
|
||||
<ClCompile Include="GPUDriverTestScreen.cpp" />
|
||||
<ClCompile Include="ImDebugger\ImDebugger.cpp" />
|
||||
<ClCompile Include="ImDebugger\ImDisasmView.cpp" />
|
||||
<ClCompile Include="ImDebugger\ImGe.cpp" />
|
||||
<ClCompile Include="ImDebugger\ImStructViewer.cpp" />
|
||||
<ClCompile Include="JitCompareScreen.cpp" />
|
||||
<ClCompile Include="JoystickHistoryView.cpp" />
|
||||
@ -96,6 +97,7 @@
|
||||
<ClInclude Include="GPUDriverTestScreen.h" />
|
||||
<ClInclude Include="ImDebugger\ImDebugger.h" />
|
||||
<ClInclude Include="ImDebugger\ImDisasmView.h" />
|
||||
<ClInclude Include="ImDebugger\ImGe.h" />
|
||||
<ClInclude Include="ImDebugger\ImStructViewer.h" />
|
||||
<ClInclude Include="JitCompareScreen.h" />
|
||||
<ClInclude Include="JoystickHistoryView.h" />
|
||||
|
@ -107,6 +107,9 @@
|
||||
<ClCompile Include="ImDebugger\ImStructViewer.cpp">
|
||||
<Filter>ImDebugger</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ImDebugger\ImGe.cpp">
|
||||
<Filter>ImDebugger</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="GameInfoCache.h" />
|
||||
@ -214,6 +217,9 @@
|
||||
<ClInclude Include="ImDebugger\ImStructViewer.h">
|
||||
<Filter>ImDebugger</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ImDebugger\ImGe.h">
|
||||
<Filter>ImDebugger</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Screens">
|
||||
|
Loading…
Reference in New Issue
Block a user