Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more GE debugger features #8762

Merged
merged 4 commits into from
May 22, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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