Skip to content

Commit

Permalink
add gfx debugger support (HarbourMasters#4345)
Browse files Browse the repository at this point in the history
Co-authored-by: Malkierian <malkierian@gmail.com>
  • Loading branch information
Archez and Malkierian authored Oct 18, 2024
1 parent ed32a28 commit f1841a2
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 12 deletions.
6 changes: 5 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,13 @@ include(CMake/GlobalSettingsInclude.cmake OPTIONAL)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)

################################################################################
# Set GBI version
# Set LUS vars
################################################################################

# Enable the Gfx debugger in LUS to use libgfxd from ZAPDTR
set(GFX_DEBUG_DISASSEMBLER ON)

# Tell LUS we're using F3DEX_GBI_2 (in a way that doesn't break libgfxd)
set(GBI_UCODE F3DEX_GBI_2)

################################################################################
Expand Down
6 changes: 6 additions & 0 deletions soh/soh/OTRGlobals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1433,6 +1433,12 @@ extern "C" void Graph_ProcessGfxCommands(Gfx* commands) {
int threshold = CVarGetInteger(CVAR_SETTING("ExtraLatencyThreshold"), 80);
wnd->SetMaximumFrameLatency(threshold > 0 && target_fps >= threshold ? 2 : 1);

// When the gfx debugger is active, only run with the final mtx
if (GfxDebuggerIsDebugging()) {
mtx_replacements.clear();
mtx_replacements.emplace_back();
}

RunCommands(commands, mtx_replacements);

last_fps = fps;
Expand Down
7 changes: 7 additions & 0 deletions soh/soh/SohGui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ namespace SohGui {

std::shared_ptr<Ship::GuiWindow> mConsoleWindow;
std::shared_ptr<Ship::GuiWindow> mStatsWindow;
std::shared_ptr<Ship::GuiWindow> mGfxDebuggerWindow;
std::shared_ptr<Ship::GuiWindow> mInputEditorWindow;

std::shared_ptr<AudioEditor> mAudioEditorWindow;
Expand Down Expand Up @@ -161,6 +162,11 @@ namespace SohGui {
SPDLOG_ERROR("Could not find console window");
}

mGfxDebuggerWindow = gui->GetGuiWindow("GfxDebuggerWindow");
if (mGfxDebuggerWindow == nullptr) {
SPDLOG_ERROR("Could not find input GfxDebuggerWindow");
}

mInputEditorWindow = gui->GetGuiWindow("Controller Configuration");
if (mInputEditorWindow == nullptr) {
SPDLOG_ERROR("Could not find input editor window");
Expand Down Expand Up @@ -237,6 +243,7 @@ namespace SohGui {
mInputEditorWindow = nullptr;
mStatsWindow = nullptr;
mConsoleWindow = nullptr;
mGfxDebuggerWindow = nullptr;
mSohMenuBar = nullptr;
mInputViewer = nullptr;
mInputViewerSettings = nullptr;
Expand Down
7 changes: 7 additions & 0 deletions soh/soh/SohMenuBar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ void DrawShipMenu() {
}

extern std::shared_ptr<Ship::GuiWindow> mInputEditorWindow;
extern std::shared_ptr<Ship::GuiWindow> mGfxDebuggerWindow;
extern std::shared_ptr<InputViewer> mInputViewer;
extern std::shared_ptr<InputViewerSettingsWindow> mInputViewerSettings;
extern std::shared_ptr<AdvancedResolutionSettings::AdvancedResolutionSettingsWindow> mAdvancedResolutionSettingsWindow;
Expand Down Expand Up @@ -1971,6 +1972,12 @@ void DrawDeveloperToolsMenu() {
mMessageViewerWindow->ToggleVisibility();
}
}
UIWidgets::Spacer(0);
if (mGfxDebuggerWindow) {
if (ImGui::Button(GetWindowButtonText("Gfx Debugger", CVarGetInteger(CVAR_WINDOW("GfxDebugger"), 0)).c_str(), ImVec2(-1.0f, 0.0f))) {
mGfxDebuggerWindow->ToggleVisibility();
}
}

ImGui::PopStyleVar(3);
ImGui::PopStyleColor(1);
Expand Down
34 changes: 23 additions & 11 deletions soh/src/code/graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@
#define GFXPOOL_HEAD_MAGIC 0x1234
#define GFXPOOL_TAIL_MAGIC 0x5678

// SOH [Port] Game State management for our render loop
static struct RunFrameContext {
GraphicsContext gfxCtx;
GameState* gameState;
GameStateOverlay* nextOvl;
GameStateOverlay* ovl;
int state;
} runFrameContext;

OSTime sGraphUpdateTime;
OSTime sGraphSetTaskTime;
FaultClient sGraphFaultClient;
Expand Down Expand Up @@ -271,6 +280,12 @@ void Graph_TaskSet00(GraphicsContext* gfxCtx) {
void Graph_Update(GraphicsContext* gfxCtx, GameState* gameState) {
u32 problem;

// Skip game frame updates while gfx debugger is active, and execute with the last frame's DL buffer
if (GfxDebuggerIsDebugging()) {
Graph_ProcessGfxCommands(runFrameContext.gfxCtx.workBuffer);
return;
}

gameState->unk_A0 = 0;
Graph_InitTHGA(gfxCtx);

Expand Down Expand Up @@ -443,15 +458,6 @@ void Graph_Update(GraphicsContext* gfxCtx, GameState* gameState) {
uint64_t GetFrequency();
uint64_t GetPerfCounter();

static struct RunFrameContext {
GraphicsContext gfxCtx;
GameState* gameState;
GameStateOverlay* nextOvl;
GameStateOverlay* ovl;
int state;
} runFrameContext;


extern AudioMgr gAudioMgr;

extern void ProcessSaveStateRequests(void);
Expand Down Expand Up @@ -515,6 +521,10 @@ static void RunFrame()
Graph_Update(&runFrameContext.gfxCtx, runFrameContext.gameState);
//ticksB = GetPerfCounter();

if (GfxDebuggerIsDebuggingRequested()) {
GfxDebuggerDebugDisplayList(runFrameContext.gfxCtx.workBuffer);
}

Graph_ProcessGfxCommands(runFrameContext.gfxCtx.workBuffer);


Expand Down Expand Up @@ -565,7 +575,8 @@ void* Graph_Alloc2(GraphicsContext* gfxCtx, size_t size) {
}

void Graph_OpenDisps(Gfx** dispRefs, GraphicsContext* gfxCtx, const char* file, s32 line) {
if (HREG(80) == 7 && HREG(82) != 4) {
// SOH [Debugging] Force open/close disp string handling on so that the graphics debugger can leverage it
if (true || HREG(80) == 7 && HREG(82) != 4) {
dispRefs[0] = gfxCtx->polyOpa.p;
dispRefs[1] = gfxCtx->polyXlu.p;
dispRefs[2] = gfxCtx->overlay.p;
Expand All @@ -577,7 +588,8 @@ void Graph_OpenDisps(Gfx** dispRefs, GraphicsContext* gfxCtx, const char* file,
}

void Graph_CloseDisps(Gfx** dispRefs, GraphicsContext* gfxCtx, const char* file, s32 line) {
if (HREG(80) == 7 && HREG(82) != 4) {
// SOH [Debugging] Force open/close disp string handling on so that the graphics debugger can leverage it
if (true || HREG(80) == 7 && HREG(82) != 4) {
if (dispRefs[0] + 1 == gfxCtx->polyOpa.p) {
gfxCtx->polyOpa.p = dispRefs[0];
} else {
Expand Down

0 comments on commit f1841a2

Please sign in to comment.