Move GE debugger breakpoints out of Windows/ code.

This commit is contained in:
Unknown W. Brackets 2013-10-12 04:02:21 -07:00
parent d6f1320dfd
commit c8d2c45590
9 changed files with 205 additions and 28 deletions

View File

@ -1004,6 +1004,8 @@ add_library(GPU OBJECT
GPU/Common/PostShader.cpp
GPU/Common/PostShader.h
GPU/Common/SplineCommon.h
GPU/Debugger/Breakpoints.cpp
GPU/Debugger/Breakpoints.h
GPU/GLES/GLES_GPU.cpp
GPU/GLES/GLES_GPU.h
GPU/GLES/FragmentShaderGenerator.cpp

View File

@ -0,0 +1,130 @@
// Copyright (c) 2013- PPSSPP Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0 or later versions.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include <vector>
#include <set>
#include "base/mutex.h"
#include "GPU/Debugger/Breakpoints.h"
namespace GPUBreakpoints {
static recursive_mutex breaksLock;
static std::vector<bool> breakCmds;
static std::set<u32> breakPCs;
// If these are set, the above are also, but they should be temporary.
static std::vector<bool> breakCmdsTemp;
static std::set<u32> breakPCsTemp;
void Init() {
ClearAllBreakpoints();
}
bool IsAddressBreakpoint(u32 addr, bool &temp) {
lock_guard guard(breaksLock);
temp = breakPCsTemp.find(addr) != breakPCsTemp.end();
return breakPCs.find(addr) != breakPCs.end();
}
bool IsAddressBreakpoint(u32 addr) {
lock_guard guard(breaksLock);
return breakPCs.find(addr) != breakPCs.end();
}
bool IsCmdBreakpoint(u8 cmd, bool &temp) {
temp = breakCmdsTemp[cmd];
return breakCmds[cmd];
}
bool IsCmdBreakpoint(u8 cmd) {
return breakCmds[cmd];
}
void AddAddressBreakpoint(u32 addr, bool temp) {
lock_guard guard(breaksLock);
if (temp) {
if (breakPCs.find(addr) == breakPCs.end()) {
breakPCsTemp.insert(addr);
breakPCs.insert(addr);
}
// Already normal breakpoint, let's not make it temporary.
} else {
// Remove the temporary marking.
breakPCsTemp.erase(addr);
breakPCs.insert(addr);
}
}
void AddCmdBreakpoint(u8 cmd, bool temp) {
if (temp) {
if (!breakCmds[cmd]) {
breakCmdsTemp[cmd] = true;
breakCmds[cmd] = true;
}
// Ignore adding a temp breakpoint when a normal one exists.
} else {
// This is no longer temporary.
breakCmdsTemp[cmd] = false;
breakCmds[cmd] = true;
}
}
void RemoveAddressBreakpoint(u32 addr) {
lock_guard guard(breaksLock);
breakPCsTemp.erase(addr);
breakPCs.erase(addr);
}
void RemoveCmdBreakpoint(u8 cmd) {
breakCmdsTemp[cmd] = false;
breakCmds[cmd] = false;
}
void ClearAllBreakpoints() {
lock_guard guard(breaksLock);
breakCmds.clear();
breakCmds.resize(256, false);
breakPCs.clear();
breakCmdsTemp.clear();
breakCmdsTemp.resize(256, false);
breakPCsTemp.clear();
}
void ClearTempBreakpoints() {
lock_guard guard(breaksLock);
// Reset ones that were temporary back to non-breakpoints in the primary arrays.
for (int i = 0; i < 256; ++i) {
if (breakCmdsTemp[i]) {
breakCmds[i] = false;
breakCmdsTemp[i] = false;
}
}
for (auto it = breakPCsTemp.begin(), end = breakPCsTemp.end(); it != end; ++it) {
breakPCs.erase(*it);
}
breakPCsTemp.clear();
}
};

View File

@ -0,0 +1,43 @@
// Copyright (c) 2013- PPSSPP Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0 or later versions.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#pragma once
#include "Common/CommonTypes.h"
namespace GPUBreakpoints {
void Init();
bool IsAddressBreakpoint(u32 addr, bool &temp);
bool IsAddressBreakpoint(u32 addr);
bool IsCmdBreakpoint(u8 cmd, bool &temp);
bool IsCmdBreakpoint(u8 cmd);
void AddAddressBreakpoint(u32 addr, bool temp = false);
void AddCmdBreakpoint(u8 cmd, bool temp = false);
void RemoveAddressBreakpoint(u32 addr);
void RemoveCmdBreakpoint(u8 cmd);
void ClearAllBreakpoints();
void ClearTempBreakpoints();
static inline bool IsOpBreakpoint(u32 op, bool &temp) {
return IsCmdBreakpoint(op >> 24, temp);
}
static inline bool IsOpBreakpoint(u32 op) {
return IsCmdBreakpoint(op >> 24);
}
};

View File

@ -160,6 +160,7 @@
<ClInclude Include="Common\PostShader.h" />
<ClInclude Include="Common\SplineCommon.h" />
<ClInclude Include="Common\VertexDecoderCommon.h" />
<ClInclude Include="Debugger\Breakpoints.h" />
<ClInclude Include="Directx9\GPU_DX9.h" />
<ClInclude Include="Directx9\helper\dx_state.h" />
<ClInclude Include="Directx9\helper\fbo.h" />
@ -203,6 +204,7 @@
<ClCompile Include="Common\IndexGenerator.cpp" />
<ClCompile Include="Common\PostShader.cpp" />
<ClCompile Include="Common\VertexDecoderCommon.cpp" />
<ClCompile Include="Debugger\Breakpoints.cpp" />
<ClCompile Include="Directx9\GPU_DX9.cpp" />
<ClCompile Include="Directx9\helper\dx_state.cpp" />
<ClCompile Include="Directx9\helper\fbo.cpp" />

View File

@ -19,6 +19,9 @@
<Filter Include="DirectX9\helper">
<UniqueIdentifier>{ba434472-5d5e-4b08-ab16-bfb7ec8e7068}</UniqueIdentifier>
</Filter>
<Filter Include="Debugger">
<UniqueIdentifier>{0cbddc00-4aa3-41d0-bed2-a454d37f838e}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ge_constants.h">
@ -148,6 +151,9 @@
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Common\PostShader.h" />
<ClInclude Include="Debugger\Breakpoints.h">
<Filter>Debugger</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Math3D.cpp">
@ -268,6 +274,9 @@
<Filter>Common</Filter>
</ClCompile>
<ClCompile Include="Common\PostShader.cpp" />
<ClCompile Include="Debugger\Breakpoints.cpp">
<Filter>Debugger</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="CMakeLists.txt" />

View File

@ -3,6 +3,7 @@
#include "Windows/InputBox.h"
#include "Windows/Main.h"
#include "Core/Config.h"
#include "GPU/Debugger/Breakpoints.h"
#include <algorithm>
const PTCHAR CtrlDisplayListView::windowClass = _T("CtrlDisplayListView");
@ -205,7 +206,7 @@ void CtrlDisplayListView::onPaint(WPARAM wParam, LPARAM lParam)
DeleteObject(backgroundPen);
// display address/symbol
if (CGEDebugger::IsAddressBreakPoint(address))
if (GPUBreakpoints::IsAddressBreakpoint(address))
{
textColor = 0x0000FF;
int yOffset = std::max(-1,(rowHeight-14+1)/2);

View File

@ -32,10 +32,13 @@
#include "GPU/GPUInterface.h"
#include "GPU/Common/GPUDebugInterface.h"
#include "GPU/GPUState.h"
#include "GPU/Debugger/Breakpoints.h"
#include "Core/Config.h"
#include <windowsx.h>
#include <commctrl.h>
using namespace GPUBreakpoints;
enum PauseAction {
PAUSE_CONTINUE,
PAUSE_BREAK,
@ -57,9 +60,6 @@ static condition_variable actionWait;
static bool actionComplete;
static recursive_mutex breaksLock;
static std::vector<bool> breakCmds;
static std::set<u32> breakPCs;
static u32 tempBreakpoint = -1;
static std::set<u32> breakTextures;
static BreakNextType breakNext = BREAK_NONE;
static u32 lastTexture = -1;
@ -84,16 +84,6 @@ void CGEDebugger::Init() {
CtrlDisplayListView::registerClass();
}
bool CGEDebugger::IsAddressBreakPoint(u32 pc) {
lock_guard guard(breaksLock);
return breakPCs.find(pc) != breakPCs.end();
}
bool CGEDebugger::IsOpBreakPoint(u32 op) {
u8 cmd = op >> 24;
return breakCmds[cmd];
}
// Hmm, this is probably kinda slow now...
bool CGEDebugger::IsTextureBreakPoint(u32 op) {
u8 cmd = op >> 24;
@ -133,7 +123,7 @@ bool CGEDebugger::IsTextureBreakPoint(u32 op) {
}
bool CGEDebugger::IsOpOrTextureBreakPoint(u32 op) {
return IsOpBreakPoint(op) || IsTextureBreakPoint(op);
return IsOpBreakpoint(op) || IsTextureBreakPoint(op);
}
static void SetPauseAction(PauseAction act, bool waitComplete = true) {
@ -199,7 +189,7 @@ static void ForceUnpause() {
CGEDebugger::CGEDebugger(HINSTANCE _hInstance, HWND _hParent)
: Dialog((LPCSTR)IDD_GEDEBUGGER, _hInstance, _hParent), frameWindow(NULL), texWindow(NULL) {
breakCmds.resize(256, false);
GPUBreakpoints::Init();
Core_ListenShutdown(ForceUnpause);
// minimum size = a little more than the default
@ -470,6 +460,7 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) {
u32 texAddr;
// TODO: Better interface that allows add/remove or something.
if (InputBox_GetHex(GetModuleHandle(NULL), m_hDlg, L"Texture Address", lastTexture, texAddr)) {
lock_guard guard(breaksLock);
if (breakTextures.find(texAddr) != breakTextures.end()) {
breakTextures.erase(texAddr);
} else {
@ -495,7 +486,7 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) {
case WM_GEDBG_BREAK_CMD:
{
u32 pc = (u32)wParam;
tempBreakpoint = -1;
ClearTempBreakpoints();
auto info = gpuDebug->DissassembleOp(pc);
NOTICE_LOG(COMMON, "Waiting at %08x, %s", pc, info.desc.c_str());
UpdatePreviews();
@ -515,21 +506,21 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) {
case WM_GEDBG_TOGGLEPCBREAKPOINT:
{
lock_guard guard(breaksLock);
u32 pc = (u32)wParam;
auto iter = breakPCs.find(pc);
if (iter != breakPCs.end())
breakPCs.erase(iter);
else
breakPCs.insert(pc);
bool temp;
bool isBreak = IsAddressBreakpoint(pc, temp);
if (isBreak && !temp) {
RemoveAddressBreakpoint(pc);
} else {
AddAddressBreakpoint(pc);
}
}
break;
case WM_GEDBG_RUNTOWPARAM:
{
lock_guard guard(breaksLock);
u32 pc = (u32)wParam;
tempBreakpoint = pc;
AddAddressBreakpoint(pc, true);
SendMessage(m_hDlg,WM_COMMAND,IDC_GEDBG_RESUME,0);
}
break;
@ -574,7 +565,7 @@ void WindowsHost::GPUNotifyCommand(u32 pc) {
u32 op = Memory::ReadUnchecked_U32(pc);
u8 cmd = op >> 24;
if (breakNext == BREAK_NEXT_OP || CGEDebugger::IsOpOrTextureBreakPoint(op) || CGEDebugger::IsAddressBreakPoint(pc) || pc == tempBreakpoint) {
if (breakNext == BREAK_NEXT_OP || CGEDebugger::IsOpOrTextureBreakPoint(op) || IsAddressBreakpoint(pc)) {
PauseWithMessage(WM_GEDBG_BREAK_CMD, (WPARAM) pc);
}
}

View File

@ -56,8 +56,6 @@ public:
static void Init();
static bool IsAddressBreakPoint(u32 pc);
static bool IsOpBreakPoint(u32 op);
static bool IsTextureBreakPoint(u32 op);
// Separate so the UI can just show op break points separately.
static bool IsOpOrTextureBreakPoint(u32 op);

View File

@ -197,6 +197,7 @@ LOCAL_SRC_FILES := \
$(SRC)/GPU/Common/VertexDecoderCommon.cpp.arm \
$(SRC)/GPU/Common/TextureDecoder.cpp \
$(SRC)/GPU/Common/PostShader.cpp \
$(SRC)/GPU/Debugger/Breakpoints.cpp \
$(SRC)/GPU/GLES/Framebuffer.cpp \
$(SRC)/GPU/GLES/GLES_GPU.cpp.arm \
$(SRC)/GPU/GLES/TextureCache.cpp.arm \