Add a simpler break on next texture.

This commit is contained in:
Unknown W. Brackets 2013-10-12 09:06:48 -07:00
parent 2584d0e67f
commit d79a9bff6d
4 changed files with 48 additions and 46 deletions

View File

@ -35,6 +35,9 @@ static size_t breakTexturesCount = 0;
static std::vector<bool> breakCmdsTemp;
static std::set<u32> breakPCsTemp;
static std::set<u32> breakTexturesTemp;
static bool textureChangeTemp = false;
static u32 lastTexture = 0xFFFFFFFF;
// These are commands we run before breaking on a texture.
// They are commands that affect the decoding of the texture.
@ -92,8 +95,19 @@ u32 GetAdjustedTextureAddress(u32 op) {
}
bool IsTextureCmdBreakpoint(u32 op) {
u32 addr = GetAdjustedTextureAddress(op);
return addr != (u32)-1 && IsTextureBreakpoint(addr);
const u32 addr = GetAdjustedTextureAddress(op);
if (addr != (u32)-1) {
const u8 cmd = op >> 24;
// Only for level 0.
if (textureChangeTemp && addr != lastTexture && (cmd == GE_CMD_TEXADDR0 || cmd == GE_CMD_TEXBUFWIDTH0)) {
textureChangeTemp = false;
lastTexture = addr;
return true;
}
return IsTextureBreakpoint(addr);
} else {
return false;
}
}
bool IsBreakpoint(u32 pc, u32 op) {
@ -101,7 +115,7 @@ bool IsBreakpoint(u32 pc, u32 op) {
return true;
}
if (breakTexturesCount != 0 && IsTextureCmdBreakpoint(op)) {
if ((breakTexturesCount != 0 || textureChangeTemp) && IsTextureCmdBreakpoint(op)) {
// Break on the next non-texture.
AddNonTextureTempBreakpoints();
}
@ -206,6 +220,10 @@ void AddTextureBreakpoint(u32 addr, bool temp) {
breakTexturesCount = breakTextures.size();
}
void AddTextureChangeTempBreakpoint() {
textureChangeTemp = true;
}
void RemoveAddressBreakpoint(u32 addr) {
lock_guard guard(breaksLock);
@ -229,6 +247,14 @@ void RemoveTextureBreakpoint(u32 addr) {
breakTexturesCount = breakTextures.size();
}
void RemoveTextureChangeTempBreakpoint() {
textureChangeTemp = false;
}
void UpdateLastTexture(u32 addr) {
lastTexture = addr;
}
void ClearAllBreakpoints() {
lock_guard guard(breaksLock);
@ -244,6 +270,8 @@ void ClearAllBreakpoints() {
breakPCsCount = breakPCs.size();
breakTexturesCount = breakTextures.size();
textureChangeTemp = false;
}
void ClearTempBreakpoints() {
@ -268,6 +296,8 @@ void ClearTempBreakpoints() {
}
breakTexturesTemp.clear();
breakPCsCount = breakTextures.size();
textureChangeTemp = false;
}
};

View File

@ -34,10 +34,14 @@ namespace GPUBreakpoints {
void AddAddressBreakpoint(u32 addr, bool temp = false);
void AddCmdBreakpoint(u8 cmd, bool temp = false);
void AddTextureBreakpoint(u32 addr, bool temp = false);
void AddTextureChangeTempBreakpoint();
void RemoveAddressBreakpoint(u32 addr);
void RemoveCmdBreakpoint(u8 cmd);
void RemoveTextureBreakpoint(u32 addr);
void RemoveTextureChangeTempBreakpoint();
void UpdateLastTexture(u32 addr);
void ClearAllBreakpoints();
void ClearTempBreakpoints();

View File

@ -60,7 +60,6 @@ static condition_variable actionWait;
static bool actionComplete;
static BreakNextType breakNext = BREAK_NONE;
static u32 lastTexture = -1;
static bool bufferResult;
static GPUDebugBuffer bufferFrame;
@ -82,40 +81,6 @@ void CGEDebugger::Init() {
CtrlDisplayListView::registerClass();
}
// Hmm, this is probably kinda slow now...
bool CGEDebugger::IsTextureBreak(u32 op) {
u8 cmd = op >> 24;
bool interesting = (cmd >= GE_CMD_TEXADDR0 && cmd <= GE_CMD_TEXADDR7);
interesting = interesting || (cmd >= GE_CMD_TEXBUFWIDTH0 && cmd <= GE_CMD_TEXBUFWIDTH7);
if (breakNext == BREAK_NEXT_NONTEX) {
// Okay, so we hit an interesting texture, but let's not break if this is a clut/etc.
// Otherwise we get garbage widths and colors. It's annoying.
bool textureCmd = interesting || cmd == GE_CMD_CLUTADDR || cmd == GE_CMD_CLUTADDRUPPER || cmd == GE_CMD_LOADCLUT || cmd == GE_CMD_CLUTFORMAT;
textureCmd = textureCmd || (cmd >= GE_CMD_TEXSIZE0 && cmd <= GE_CMD_TEXSIZE7);
textureCmd = textureCmd || cmd == GE_CMD_TEXFORMAT || cmd == GE_CMD_TEXMODE || cmd == GE_CMD_TEXTUREMAPENABLE;
if (!textureCmd) {
return true;
}
}
if (!interesting || !gpuDebug) {
return false;
}
// Okay, so we just set a texture of some sort, check if it was one we were waiting for.
auto state = gpuDebug->GetGState();
int level = cmd <= GE_CMD_TEXADDR7 ? cmd - GE_CMD_TEXADDR0 : cmd - GE_CMD_TEXBUFWIDTH0;
// Are we breaking on any texture? As long as it's level 0.
if (level == 0 && breakNext == BREAK_NEXT_TEX && lastTexture != state.getTextureAddress(level)) {
// Don't break right away, we'll get a garbage texture...
breakNext = BREAK_NEXT_NONTEX;
}
return false;
}
static void SetPauseAction(PauseAction act, bool waitComplete = true) {
{
lock_guard guard(pauseLock);
@ -315,9 +280,9 @@ void CGEDebugger::UpdatePreviews() {
_snwprintf(desc, ARRAY_SIZE(desc), L"Texture: 0x%08x (%dx%d)", state.getTextureAddress(0), state.getTextureWidth(0), state.getTextureHeight(0));
SetDlgItemText(m_hDlg, IDC_GEDBG_TEXADDR, desc);
lastTexture = state.getTextureAddress(0);
UpdateLastTexture(state.getTextureAddress(0));
} else {
lastTexture = -1;
UpdateLastTexture((u32)-1);
}
} else {
texWindow->Clear();
@ -326,7 +291,7 @@ void CGEDebugger::UpdatePreviews() {
} else {
SetDlgItemText(m_hDlg, IDC_GEDBG_TEXADDR, L"Texture: disabled");
}
lastTexture = -1;
UpdateLastTexture((u32)-1);
}
DisplayList list;
@ -438,6 +403,7 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) {
break;
case IDC_GEDBG_STEPTEX:
AddTextureChangeTempBreakpoint();
SetBreakNext(BREAK_NEXT_TEX);
break;
@ -447,9 +413,13 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) {
case IDC_GEDBG_BREAKTEX:
{
u32 texAddr;
if (!gpuDebug) {
break;
}
const auto state = gpuDebug->GetGState();
u32 texAddr = state.getTextureAddress(0);
// TODO: Better interface that allows add/remove or something.
if (InputBox_GetHex(GetModuleHandle(NULL), m_hDlg, L"Texture Address", lastTexture, texAddr)) {
if (InputBox_GetHex(GetModuleHandle(NULL), m_hDlg, L"Texture Address", texAddr, texAddr)) {
if (IsTextureBreakpoint(texAddr)) {
RemoveTextureBreakpoint(texAddr);
} else {
@ -554,7 +524,7 @@ void WindowsHost::GPUNotifyCommand(u32 pc) {
u32 op = Memory::ReadUnchecked_U32(pc);
u8 cmd = op >> 24;
if (breakNext == BREAK_NEXT_OP || CGEDebugger::IsTextureBreak(op) || IsBreakpoint(pc, op)) {
if (breakNext == BREAK_NEXT_OP || IsBreakpoint(pc, op)) {
PauseWithMessage(WM_GEDBG_BREAK_CMD, (WPARAM) pc);
}
}

View File

@ -56,8 +56,6 @@ public:
static void Init();
static bool IsTextureBreak(u32 op);
protected:
BOOL DlgProc(UINT message, WPARAM wParam, LPARAM lParam);