Skip to content

Commit

Permalink
Merge pull request #8762 from unknownbrackets/debugger
Browse files Browse the repository at this point in the history
Add more GE debugger features
  • Loading branch information
hrydgard committed May 22, 2016
2 parents dc69aba + 8b56698 commit 8d87a5b
Show file tree
Hide file tree
Showing 8 changed files with 270 additions and 19 deletions.
97 changes: 96 additions & 1 deletion GPU/Debugger/Breakpoints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,17 @@ static recursive_mutex breaksLock;
static std::vector<bool> breakCmds;
static std::set<u32> breakPCs;
static std::set<u32> breakTextures;
static std::set<u32> breakRenderTargets;
// Small optimization to avoid a lock/lookup for the common case.
static size_t breakPCsCount = 0;
static size_t breakTexturesCount = 0;
static size_t breakRenderTargetsCount = 0;

// If these are set, the above are also, but they should be temporary.
static std::vector<bool> breakCmdsTemp;
static std::set<u32> breakPCsTemp;
static std::set<u32> breakTexturesTemp;
static std::set<u32> breakRenderTargetsTemp;
static bool textureChangeTemp = false;

static u32 lastTexture = 0xFFFFFFFF;
Expand Down Expand Up @@ -96,6 +99,17 @@ u32 GetAdjustedTextureAddress(u32 op) {
return addr;
}

u32 GetAdjustedRenderTargetAddress(u32 op) {
const u8 cmd = op >> 24;
switch (cmd) {
case GE_CMD_FRAMEBUFPTR:
case GE_CMD_ZBUFPTR:
return op & 0x003FFFF0;
}

return (u32)-1;
}

bool IsTextureChangeBreakpoint(u32 op, u32 addr) {
if (!textureChangeTemp) {
return false;
Expand Down Expand Up @@ -131,6 +145,14 @@ bool IsTextureCmdBreakpoint(u32 op) {
}
}

bool IsRenderTargetCmdBreakpoint(u32 op) {
const u32 addr = GetAdjustedRenderTargetAddress(op);
if (addr != (u32)-1) {
return IsRenderTargetBreakpoint(addr);
}
return false;
}

bool IsBreakpoint(u32 pc, u32 op) {
if (IsAddressBreakpoint(pc) || IsOpBreakpoint(op)) {
return true;
Expand All @@ -140,6 +162,9 @@ bool IsBreakpoint(u32 pc, u32 op) {
// Break on the next non-texture.
AddNonTextureTempBreakpoints();
}
if (breakRenderTargetsCount != 0 && IsRenderTargetCmdBreakpoint(op)) {
return true;
}

return false;
}
Expand Down Expand Up @@ -184,6 +209,38 @@ bool IsTextureBreakpoint(u32 addr) {
return breakTextures.find(addr) != breakTextures.end();
}

bool IsRenderTargetBreakpoint(u32 addr, bool &temp) {
if (breakRenderTargetsCount == 0) {
temp = false;
return false;
}

addr &= 0x003FFFF0;

lock_guard guard(breaksLock);
temp = breakRenderTargetsTemp.find(addr) != breakRenderTargetsTemp.end();
return breakRenderTargets.find(addr) != breakRenderTargets.end();
}

bool IsRenderTargetBreakpoint(u32 addr) {
if (breakRenderTargetsCount == 0) {
return false;
}

addr &= 0x003FFFF0;

lock_guard guard(breaksLock);
return breakRenderTargets.find(addr) != breakRenderTargets.end();
}

bool IsOpBreakpoint(u32 op, bool &temp) {
return IsCmdBreakpoint(op >> 24, temp);
}

bool IsOpBreakpoint(u32 op) {
return IsCmdBreakpoint(op >> 24);
}

bool IsCmdBreakpoint(u8 cmd, bool &temp) {
temp = breakCmdsTemp[cmd];
return breakCmds[cmd];
Expand Down Expand Up @@ -241,6 +298,24 @@ void AddTextureBreakpoint(u32 addr, bool temp) {
breakTexturesCount = breakTextures.size();
}

void AddRenderTargetBreakpoint(u32 addr, bool temp) {
lock_guard guard(breaksLock);

addr &= 0x003FFFF0;

if (temp) {
if (breakRenderTargets.find(addr) == breakRenderTargets.end()) {
breakRenderTargetsTemp.insert(addr);
breakRenderTargets.insert(addr);
}
} else {
breakRenderTargetsTemp.erase(addr);
breakRenderTargets.insert(addr);
}

breakRenderTargetsCount = breakRenderTargets.size();
}

void AddTextureChangeTempBreakpoint() {
textureChangeTemp = true;
}
Expand Down Expand Up @@ -268,6 +343,17 @@ void RemoveTextureBreakpoint(u32 addr) {
breakTexturesCount = breakTextures.size();
}

void RemoveRenderTargetBreakpoint(u32 addr) {
lock_guard guard(breaksLock);

addr &= 0x003FFFF0;

breakRenderTargetsTemp.erase(addr);
breakRenderTargets.erase(addr);

breakRenderTargetsCount = breakRenderTargets.size();
}

void RemoveTextureChangeTempBreakpoint() {
textureChangeTemp = false;
}
Expand All @@ -283,14 +369,17 @@ void ClearAllBreakpoints() {
breakCmds.resize(256, false);
breakPCs.clear();
breakTextures.clear();
breakRenderTargets.clear();

breakCmdsTemp.clear();
breakCmdsTemp.resize(256, false);
breakPCsTemp.clear();
breakTexturesTemp.clear();
breakRenderTargetsTemp.clear();

breakPCsCount = breakPCs.size();
breakTexturesCount = breakTextures.size();
breakRenderTargetsCount = breakRenderTargets.size();

textureChangeTemp = false;
}
Expand All @@ -316,7 +405,13 @@ void ClearTempBreakpoints() {
breakTextures.erase(*it);
}
breakTexturesTemp.clear();
breakPCsCount = breakTextures.size();
breakTexturesCount = breakTextures.size();

for (auto it = breakRenderTargetsTemp.begin(), end = breakRenderTargetsTemp.end(); it != end; ++it) {
breakRenderTargets.erase(*it);
}
breakRenderTargetsTemp.clear();
breakRenderTargetsCount = breakRenderTargets.size();

textureChangeTemp = false;
}
Expand Down
12 changes: 6 additions & 6 deletions GPU/Debugger/Breakpoints.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,27 +30,27 @@ namespace GPUBreakpoints {
bool IsCmdBreakpoint(u8 cmd);
bool IsTextureBreakpoint(u32 addr, bool &temp);
bool IsTextureBreakpoint(u32 addr);
bool IsRenderTargetBreakpoint(u32 addr, bool &temp);
bool IsRenderTargetBreakpoint(u32 addr);

void AddAddressBreakpoint(u32 addr, bool temp = false);
void AddCmdBreakpoint(u8 cmd, bool temp = false);
void AddTextureBreakpoint(u32 addr, bool temp = false);
void AddTextureChangeTempBreakpoint();
void AddRenderTargetBreakpoint(u32 addr, bool temp = false);

void RemoveAddressBreakpoint(u32 addr);
void RemoveCmdBreakpoint(u8 cmd);
void RemoveTextureBreakpoint(u32 addr);
void RemoveTextureChangeTempBreakpoint();
void RemoveRenderTargetBreakpoint(u32 addr);

void UpdateLastTexture(u32 addr);

void ClearAllBreakpoints();
void ClearTempBreakpoints();

static inline bool IsOpBreakpoint(u32 op, bool &temp) {
return IsCmdBreakpoint(op >> 24, temp);
}
bool IsOpBreakpoint(u32 op, bool &temp);

static inline bool IsOpBreakpoint(u32 op) {
return IsCmdBreakpoint(op >> 24);
}
bool IsOpBreakpoint(u32 op);
};
30 changes: 30 additions & 0 deletions Windows/GEDebugger/GEDebugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ CGEDebugger::CGEDebugger(HINSTANCE _hInstance, HWND _hParent)
lists = new TabDisplayLists(_hInstance, m_hDlg);
tabs->AddTabDialog(lists, L"Lists");

watch = new TabStateWatch(_hInstance, m_hDlg);
tabs->AddTabDialog(watch, L"Watch");

tabs->ShowTab(0, true);

// set window position
Expand All @@ -135,6 +138,7 @@ CGEDebugger::~CGEDebugger() {
delete vertices;
delete matrices;
delete lists;
delete watch;
delete tabs;
delete fbTabs;
}
Expand Down Expand Up @@ -225,6 +229,7 @@ void CGEDebugger::UpdatePreviews() {
vertices->Update();
matrices->Update();
lists->Update();
watch->Update();
}

u32 CGEDebugger::TexturePreviewFlags(const GPUgstate &state) {
Expand Down Expand Up @@ -658,6 +663,25 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) {
}
break;

case IDC_GEDBG_BREAKTARGET:
{
attached = true;
if (!gpuDebug) {
break;
}
const auto state = gpuDebug->GetGState();
u32 fbAddr = state.getFrameBufRawAddress();
// TODO: Better interface that allows add/remove or something.
if (InputBox_GetHex(GetModuleHandle(NULL), m_hDlg, L"Framebuffer Address", fbAddr, fbAddr)) {
if (IsRenderTargetBreakpoint(fbAddr)) {
RemoveRenderTargetBreakpoint(fbAddr);
} else {
AddRenderTargetBreakpoint(fbAddr);
}
}
}
break;

case IDC_GEDBG_TEXLEVELDOWN:
UpdateTextureLevel(textureLevel_ - 1);
if (attached && gpuDebug != nullptr) {
Expand Down Expand Up @@ -747,6 +771,12 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) {
GPU_SetCmdValue((u32)wParam);
}
break;

case WM_GEDBG_UPDATE_WATCH:
// Just a notification to update.
if (watch)
watch->Update();
break;
}

return FALSE;
Expand Down
3 changes: 3 additions & 0 deletions Windows/GEDebugger/GEDebugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ enum {
WM_GEDBG_TOGGLEPCBREAKPOINT,
WM_GEDBG_RUNTOWPARAM,
WM_GEDBG_SETCMDWPARAM,
WM_GEDBG_UPDATE_WATCH,
};

enum BreakNextType {
Expand All @@ -52,6 +53,7 @@ class TabStateTexture;
class TabStateSettings;
class TabVertices;
class TabMatrices;
class TabStateWatch;
struct GPUgstate;

class CGEDebugger : public Dialog {
Expand Down Expand Up @@ -94,6 +96,7 @@ class CGEDebugger : public Dialog {
TabMatrices *matrices;
SimpleGLWindow *primaryWindow;
SimpleGLWindow *secondWindow;
TabStateWatch *watch;
TabControl *tabs;
TabControl *fbTabs;
int textureLevel_;
Expand Down
Loading

0 comments on commit 8d87a5b

Please sign in to comment.