From 5aeef924d27eec8759abe9622d5e8a8d8cbe46a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 12 Dec 2024 23:35:58 +0100 Subject: [PATCH] Implement vertex preview in the new Ge debugger --- GPU/Debugger/State.cpp | 4 +- GPU/Debugger/State.h | 2 +- UI/ImDebugger/ImDebugger.cpp | 4 +- UI/ImDebugger/ImDebugger.h | 3 ++ UI/ImDebugger/ImGe.cpp | 71 +++++++++++++++++++++++++++- UI/ImDebugger/ImGe.h | 12 ++++- Windows/GEDebugger/VertexPreview.cpp | 6 ++- 7 files changed, 93 insertions(+), 9 deletions(-) diff --git a/GPU/Debugger/State.cpp b/GPU/Debugger/State.cpp index 54d5be6062..4398d79768 100644 --- a/GPU/Debugger/State.cpp +++ b/GPU/Debugger/State.cpp @@ -831,7 +831,7 @@ static void ExpandSpline(int &count, int op, const std::vector &si FreeAlignedMemory(cpoints.col); } -bool GetPrimPreview(u32 op, int which, GEPrimitiveType &prim, std::vector &vertices, std::vector &indices, int &count) { +bool GetPrimPreview(u32 op, GEPrimitiveType &prim, std::vector &vertices, std::vector &indices, int &count) { u32 prim_type = GE_PRIM_INVALID; int count_u = 0; int count_v = 0; @@ -857,7 +857,7 @@ bool GetPrimPreview(u32 op, int which, GEPrimitiveType &prim, std::vector &vertices, std::vector &indices, int &count); +bool GetPrimPreview(u32 op, GEPrimitiveType &prim, std::vector &vertices, std::vector &indices, int &count); void DescribePixel(u32 pix, GPUDebugBufferFormat fmt, int x, int y, char desc[256]); void DescribePixelRGBA(u32 pix, GPUDebugBufferFormat fmt, int x, int y, char desc[256]); diff --git a/UI/ImDebugger/ImDebugger.cpp b/UI/ImDebugger/ImDebugger.cpp index b4b4939c5d..4acde09d85 100644 --- a/UI/ImDebugger/ImDebugger.cpp +++ b/UI/ImDebugger/ImDebugger.cpp @@ -902,14 +902,14 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebu if (lastCpuStepCount_ != Core_GetSteppingCounter()) { lastCpuStepCount_ = Core_GetSteppingCounter(); - disasm_.View().NotifyStep(); + disasm_.NotifyStep(); } if (lastGpuStepCount_ != GPUStepping::GetSteppingCounter()) { // A GPU step has happened since last time. This means that we should re-center the cursor. // Snapshot(); lastGpuStepCount_ = GPUStepping::GetSteppingCounter(); - geDebugger_.View().NotifyStep(); + geDebugger_.NotifyStep(); } ImControl control{}; diff --git a/UI/ImDebugger/ImDebugger.h b/UI/ImDebugger/ImDebugger.h index 1af95f0169..9ffb9ce7bb 100644 --- a/UI/ImDebugger/ImDebugger.h +++ b/UI/ImDebugger/ImDebugger.h @@ -36,6 +36,9 @@ public: ImDisasmView &View() { return disasmView_; } + void NotifyStep() { + disasmView_.NotifyStep(); + } void DirtySymbolMap() { symsDirty_ = true; } diff --git a/UI/ImDebugger/ImGe.cpp b/UI/ImDebugger/ImGe.cpp index d5e73da10e..71aac55dcb 100644 --- a/UI/ImDebugger/ImGe.cpp +++ b/UI/ImDebugger/ImGe.cpp @@ -367,8 +367,26 @@ void ImGeDebuggerWindow::Draw(ImConfig &cfg, ImControl &control, GPUDebugInterfa ImGui::SameLine(); + u32 op = 0; + DisplayList list; + if (gpuDebug->GetCurrentDisplayList(list)) { + op = Memory::Read_U32(list.pc); + bool isOnPrim = (op >> 24) == GE_CMD_PRIM; + if (isOnPrim) { + if (reloadPreview_) { + GetPrimPreview(op, previewPrim_, previewVertices_, previewIndices_, previewCount_); + reloadPreview_ = false; + } + } else { + previewCount_ = 0; + } + } + ImGui::BeginChild("texture/fb view"); // Leave room for 1 line below us + + ImDrawList *drawList = ImGui::GetWindowDrawList(); + if (coreState == CORE_STEPPING_GE) { FramebufferManagerCommon *fbman = gpuDebug->GetFramebufferManagerCommon(); u32 fbptr = gstate.getFrameBufAddress(); @@ -384,8 +402,31 @@ void ImGeDebuggerWindow::Draw(ImConfig &cfg, ImControl &control, GPUDebugInterfa if (ImGui::BeginTabBar("aspects")) { if (ImGui::BeginTabItem("Color")) { ImTextureID texId = ImGui_ImplThin3d_AddFBAsTextureTemp(vfb->fbo, Draw::FB_COLOR_BIT, ImGuiPipeline::TexturedOpaque); + const ImVec2 p0 = ImGui::GetCursorScreenPos(); ImGui::Image(texId, ImVec2(vfb->width, vfb->height)); - // TODO: Draw vertex preview on top! + // Draw vertex preview on top! + if (previewCount_) { + switch (previewPrim_) { + case GE_PRIM_TRIANGLES: + case GE_PRIM_RECTANGLES: + { + for (int i = 0; i < previewCount_ - 2; i += 3) { + const auto &v1 = previewIndices_.empty() ? previewVertices_[i] : previewVertices_[previewIndices_[i]]; + const auto &v2 = previewIndices_.empty() ? previewVertices_[i + 1] : previewVertices_[previewIndices_[i + 1]]; + const auto &v3 = previewIndices_.empty() ? previewVertices_[i + 2] : previewVertices_[previewIndices_[i + 2]]; + drawList->AddTriangleFilled( + ImVec2(p0.x + v1.x, p0.y + v1.y), + ImVec2(p0.x + v2.x, p0.y + v2.y), + ImVec2(p0.x + v3.x, p0.y + v3.y), ImColor(0x600000FF)); + } + break; + } + default: + // TODO: Support lines etc. + break; + } + } + ImGui::EndTabItem(); } if (ImGui::BeginTabItem("Depth")) { @@ -415,7 +456,33 @@ void ImGeDebuggerWindow::Draw(ImConfig &cfg, ImControl &control, GPUDebugInterfa void *nativeView = texcache->GetNativeTextureView(tex, true); ImTextureID texId = ImGui_ImplThin3d_AddNativeTextureTemp(nativeView); - ImGui::Image(texId, ImVec2(128, 128)); + const ImVec2 p0 = ImGui::GetCursorScreenPos(); + float texW = dimWidth(tex->dim); + float texH = dimHeight(tex->dim); + ImGui::Image(texId, ImVec2(texW, texH)); + + // Draw UVs of vertex preview on top of the texture! + if (previewCount_) { + switch (previewPrim_) { + case GE_PRIM_TRIANGLES: + case GE_PRIM_RECTANGLES: + { + for (int i = 0; i < previewCount_ - 2; i += 3) { + const auto &v1 = previewIndices_.empty() ? previewVertices_[i] : previewVertices_[previewIndices_[i]]; + const auto &v2 = previewIndices_.empty() ? previewVertices_[i + 1] : previewVertices_[previewIndices_[i + 1]]; + const auto &v3 = previewIndices_.empty() ? previewVertices_[i + 2] : previewVertices_[previewIndices_[i + 2]]; + drawList->AddTriangleFilled( + ImVec2(p0.x + v1.u * texW, p0.y + v1.v * texH), + ImVec2(p0.x + v2.u * texW, p0.y + v2.v * texH), + ImVec2(p0.x + v3.u * texW, p0.y + v3.v * texH), ImColor(0x600000FF)); + } + break; + } + default: + // TODO: Support lines etc. + break; + } + } // Let's display the current CLUT. diff --git a/UI/ImDebugger/ImGe.h b/UI/ImDebugger/ImGe.h index f4cadbda75..fda9d3e2bd 100644 --- a/UI/ImDebugger/ImGe.h +++ b/UI/ImDebugger/ImGe.h @@ -1,5 +1,7 @@ #pragma once +#include "GPU/Common/GPUDebugInterface.h" + // GE-related windows of the ImDebugger struct ImConfig; @@ -7,7 +9,6 @@ struct ImControl; class FramebufferManagerCommon; class TextureCacheCommon; -class GPUDebugInterface; void DrawFramebuffersWindow(ImConfig &cfg, FramebufferManagerCommon *framebufferManager); void DrawTexturesWindow(ImConfig &cfg, TextureCacheCommon *textureCache); @@ -57,8 +58,17 @@ public: const char *Title() const { return "GE Debugger"; } + void NotifyStep() { + reloadPreview_ = true; + disasmView_.NotifyStep(); + } private: ImGeDisasmView disasmView_; int showBannerInFrames_ = 0; + bool reloadPreview_ = false; + GEPrimitiveType previewPrim_; + std::vector previewIndices_; + std::vector previewVertices_; + int previewCount_ = 0; }; diff --git a/Windows/GEDebugger/VertexPreview.cpp b/Windows/GEDebugger/VertexPreview.cpp index 486c989321..eaf4fdc503 100644 --- a/Windows/GEDebugger/VertexPreview.cpp +++ b/Windows/GEDebugger/VertexPreview.cpp @@ -89,12 +89,16 @@ u32 CGEDebugger::PrimPreviewOp() { void CGEDebugger::UpdatePrimPreview(u32 op, int which) { which &= previewsEnabled_; + if (which == 0) { + return; + } + static std::vector vertices; static std::vector indices; int count = 0; GEPrimitiveType prim; - if (!GetPrimPreview(op, which, prim, vertices, indices, count)) { + if (!GetPrimPreview(op, prim, vertices, indices, count)) { return; }