GE Debugger: Allow modify/breakpoint on matrix.

This commit is contained in:
Unknown W. Brackets
2022-02-06 00:16:35 -08:00
parent 72b2fbf635
commit 459bb83c23
6 changed files with 210 additions and 28 deletions
+4 -4
View File
@@ -993,9 +993,9 @@ bool GPUCommon::InterpretList(DisplayList &list) {
gpuState = list.pc == list.stall ? GPUSTATE_STALL : GPUSTATE_RUNNING;
debugRecording_ = GPURecord::IsActive();
const bool useDebugger = GPUDebug::IsActive() || debugRecording_;
const bool useFastRunLoop = !dumpThisFrame_ && !useDebugger;
// To enable breakpoints, we don't do fast matrix loads while debugger active.
debugRecording_ = GPUDebug::IsActive() || GPURecord::IsActive();
const bool useFastRunLoop = !dumpThisFrame_ && !debugRecording_;
while (gpuState == GPUSTATE_RUNNING) {
{
if (list.pc == list.stall) {
@@ -1679,7 +1679,7 @@ void GPUCommon::Execute_Prim(u32 op, u32 diff) {
if (!g_Config.bSoftwareSkinning)
vtypeCheckMask = 0xFFFFFFFF;
if (debugRecording_ || GPUDebug::IsActive())
if (debugRecording_)
goto bail;
while (src != stall) {
+2 -2
View File
@@ -331,7 +331,7 @@ bool PromptStateValue(const TabStateRow &info, HWND hparent, const wchar_t *titl
CtrlStateValues::CtrlStateValues(const TabStateRow *rows, int rowCount, HWND hwnd)
: GenericListControl(hwnd, stateValuesListDef),
rows_(rows), rowCount_(rowCount) {
SetIconList(12, 12, { (HICON)LoadIcon(GetModuleHandle(0), (LPCWSTR)IDI_BREAKPOINT_SMALL) });
SetIconList(12, 12, { (HICON)LoadIcon(GetModuleHandle(nullptr), (LPCWSTR)IDI_BREAKPOINT_SMALL) });
Update();
}
@@ -889,7 +889,7 @@ void CtrlStateValues::GetColumnText(wchar_t *dest, int row, int col) {
}
void CtrlStateValues::OnDoubleClick(int row, int column) {
if (gpuDebug == nullptr || row > rowCount_) {
if (gpuDebug == nullptr || row >= rowCount_) {
return;
}
+183 -19
View File
@@ -16,14 +16,18 @@
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include "Common/CommonTypes.h"
#include "Common/StringUtils.h"
#include "Core/System.h"
#include "Windows/resource.h"
#include "Windows/InputBox.h"
#include "Windows/GEDebugger/GEDebugger.h"
#include "Windows/GEDebugger/TabVertices.h"
#include "Windows/W32Util/ContextMenu.h"
#include "GPU/Common/VertexDecoderCommon.h"
#include "GPU/GPUState.h"
#include "GPU/GeDisasm.h"
#include "GPU/Common/GPUDebugInterface.h"
#include "GPU/Debugger/Breakpoints.h"
static const GenericListViewColumn vertexListCols[] = {
{ L"X", 0.1f },
@@ -55,7 +59,8 @@ enum VertexListCols {
};
static const GenericListViewColumn matrixListCols[] = {
{ L"Name", 0.24f },
{ L"", 0.03f },
{ L"Name", 0.21f },
{ L"0", 0.19f },
{ L"1", 0.19f },
{ L"2", 0.19f },
@@ -67,6 +72,7 @@ GenericListViewDef matrixListDef = {
};
enum MatrixListCols {
MATRIXLIST_COL_BREAKPOINT,
MATRIXLIST_COL_NAME,
MATRIXLIST_COL_0,
MATRIXLIST_COL_1,
@@ -360,81 +366,118 @@ BOOL TabVertices::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) {
CtrlMatrixList::CtrlMatrixList(HWND hwnd)
: GenericListControl(hwnd, matrixListDef) {
SetIconList(12, 12, { (HICON)LoadIcon(GetModuleHandle(nullptr), (LPCWSTR)IDI_BREAKPOINT_SMALL) });
Update();
}
bool CtrlMatrixList::GetValue(int row, int col, float &val) {
if (!gpuDebug || row < 0 || row >= MATRIXLIST_ROW_COUNT || col < 0 || col >= MATRIXLIST_COL_COUNT)
return false;
if (col < MATRIXLIST_COL_0)
col = MATRIXLIST_COL_0;
auto state = gpuDebug->GetGState();
if (row >= MATRIXLIST_ROW_BONE_0_0) {
int b = (row - MATRIXLIST_ROW_BONE_0_0) / 3;
int r = (row - MATRIXLIST_ROW_BONE_0_0) % 3;
int offset = b * 12 + r + (col - MATRIXLIST_COL_0) * 3;
val = state.boneMatrix[offset];
return true;
} else if (row >= MATRIXLIST_ROW_TGEN_0) {
int r = row - MATRIXLIST_ROW_TGEN_0;
int offset = r + (col - MATRIXLIST_COL_0) * 3;
val = state.tgenMatrix[offset];
return true;
} else if (row >= MATRIXLIST_ROW_PROJ_0) {
int r = row - MATRIXLIST_ROW_PROJ_0;
int offset = r + (col - MATRIXLIST_COL_0) * 4;
val = state.projMatrix[offset];
return true;
} else if (row >= MATRIXLIST_ROW_VIEW_0) {
int r = row - MATRIXLIST_ROW_VIEW_0;
int offset = r + (col - MATRIXLIST_COL_0) * 3;
val = state.viewMatrix[offset];
return true;
}
int r = row - MATRIXLIST_ROW_WORLD_0;
int offset = r + (col - MATRIXLIST_COL_0) * 3;
val = state.worldMatrix[offset];
return true;
}
void CtrlMatrixList::GetColumnText(wchar_t *dest, int row, int col) {
if (!gpuDebug || row < 0 || row >= MATRIXLIST_ROW_COUNT || col < 0 || col >= MATRIXLIST_COL_COUNT) {
if (col == MATRIXLIST_COL_BREAKPOINT) {
wcscpy(dest, L" ");
return;
}
float val;
if (!GetValue(row, col, val)) {
wcscpy(dest, L"Invalid");
return;
}
auto state = gpuDebug->GetGState();
if (row >= MATRIXLIST_ROW_BONE_0_0) {
int b = (row - MATRIXLIST_ROW_BONE_0_0) / 3;
int r = (row - MATRIXLIST_ROW_BONE_0_0) % 3;
int offset = b * 12 + r + (col - 1) * 3;
switch (col) {
case MATRIXLIST_COL_NAME:
swprintf(dest, 255, L"Bone #%d row %d", b, r);
break;
default:
swprintf(dest, 255, L"%f", state.boneMatrix[offset]);
swprintf(dest, 255, L"%f", val);
break;
}
} else if (row >= MATRIXLIST_ROW_TGEN_0) {
int r = row - MATRIXLIST_ROW_TGEN_0;
int offset = r + (col - 1) * 4;
switch (col) {
case MATRIXLIST_COL_NAME:
swprintf(dest, 255, L"Texgen %d", r);
break;
default:
swprintf(dest, 255, L"%f", state.tgenMatrix[offset]);
swprintf(dest, 255, L"%f", val);
break;
}
} else if (row >= MATRIXLIST_ROW_PROJ_0) {
int r = row - MATRIXLIST_ROW_PROJ_0;
int offset = r + (col - 1) * 4;
switch (col) {
case MATRIXLIST_COL_NAME:
swprintf(dest, 255, L"Proj %d", r);
break;
default:
swprintf(dest, 255, L"%f", state.projMatrix[offset]);
swprintf(dest, 255, L"%f", val);
break;
}
} else if (row >= MATRIXLIST_ROW_VIEW_0) {
int r = row - MATRIXLIST_ROW_VIEW_0;
int offset = r + (col - 1) * 3;
switch (col) {
case MATRIXLIST_COL_NAME:
swprintf(dest, 255, L"View %d", r);
break;
default:
swprintf(dest, 255, L"%f", state.viewMatrix[offset]);
swprintf(dest, 255, L"%f", val);
break;
}
} else {
int r = row - MATRIXLIST_ROW_WORLD_0;
int offset = r + (col - 1) * 3;
switch (col) {
case MATRIXLIST_COL_NAME:
swprintf(dest, 255, L"World %d", r);
break;
default:
swprintf(dest, 255, L"%f", state.worldMatrix[offset]);
swprintf(dest, 255, L"%f", val);
break;
}
}
@@ -448,6 +491,127 @@ int CtrlMatrixList::GetRowCount() {
return MATRIXLIST_ROW_COUNT;
}
struct MatrixCmdPair {
MatrixListRows row;
GECommand numCmd;
GECommand cmd;
};
static constexpr MatrixCmdPair matrixCmds[] = {
{ MATRIXLIST_ROW_WORLD_0, GE_CMD_WORLDMATRIXNUMBER, GE_CMD_WORLDMATRIXDATA },
{ MATRIXLIST_ROW_VIEW_0, GE_CMD_VIEWMATRIXNUMBER, GE_CMD_VIEWMATRIXDATA },
{ MATRIXLIST_ROW_PROJ_0, GE_CMD_PROJMATRIXNUMBER, GE_CMD_PROJMATRIXDATA },
{ MATRIXLIST_ROW_TGEN_0, GE_CMD_TGENMATRIXNUMBER, GE_CMD_TGENMATRIXDATA },
{ MATRIXLIST_ROW_BONE_0_0, GE_CMD_BONEMATRIXNUMBER, GE_CMD_BONEMATRIXDATA },
{ MATRIXLIST_ROW_COUNT, GE_CMD_NOP },
};
void CtrlMatrixList::ToggleBreakpoint(int row) {
for (int i = 0; i < ARRAY_SIZE(matrixCmds) - 1; ++i) {
if (row < matrixCmds[i].row || row >= matrixCmds[i + 1].row)
continue;
// Okay, this command is in range. Toggle the actual breakpoint.
auto &info = matrixCmds[i];
bool state = !GPUBreakpoints::IsCmdBreakpoint(info.cmd);
if (state)
GPUBreakpoints::AddCmdBreakpoint(info.cmd);
else
GPUBreakpoints::RemoveCmdBreakpoint(info.cmd);
for (int r = matrixCmds[i].row; r < matrixCmds[i + 1].row; ++r) {
SetItemState(r, state ? 1 : 0);
}
}
}
void CtrlMatrixList::OnDoubleClick(int row, int column) {
if (row >= GetRowCount())
return;
if (column == MATRIXLIST_COL_BREAKPOINT) {
ToggleBreakpoint(row);
return;
}
float val;
if (!GetValue(row, column, val))
return;
std::string strvalue = StringFromFormat("%f", val);
bool res = InputBox_GetString(GetModuleHandle(NULL), GetHandle(), L"Column value", strvalue, strvalue);
if (!res)
return;
if (sscanf(strvalue.c_str(), "%f", &val) == 1) {
auto prevState = gpuDebug->GetGState();
auto setCmdValue = [&](u32 op) {
SendMessage(GetParent(GetParent(GetHandle())), WM_GEDBG_SETCMDWPARAM, op, NULL);
};
union {
float f;
u32 u;
} temp = { val };
for (int i = 0; i < ARRAY_SIZE(matrixCmds) - 1; ++i) {
if (row < matrixCmds[i].row || row >= matrixCmds[i + 1].row)
continue;
// Everything is 3 except the projection matrix, which is 4.
int sz = matrixCmds[i + 1].row - matrixCmds[i].row == 4 ? 4 : 3;
// Always zero except for bones.
int b = (row - matrixCmds[i].row) / sz;
int r = (row - matrixCmds[i].row) % sz;
int c = column >= MATRIXLIST_COL_0 ? column - MATRIXLIST_COL_0 : 0;
// Okay, now set the number, then data.
int n = b * 12 + r + c * sz;
setCmdValue((matrixCmds[i].numCmd << 24) | n);
setCmdValue((matrixCmds[i].cmd << 24) | (temp.u >> 8));
// Done, revert the number.
setCmdValue(prevState.cmdmem[matrixCmds[i].numCmd]);
Update();
}
}
}
void CtrlMatrixList::OnRightClick(int row, int column, const POINT &point) {
if (row >= GetRowCount())
return;
POINT screenPt(point);
ClientToScreen(GetHandle(), &screenPt);
HMENU subMenu = GetContextMenu(ContextMenuID::GEDBG_MATRIX);
SetMenuDefaultItem(subMenu, ID_REGLIST_CHANGE, FALSE);
switch (TriggerContextMenu(ContextMenuID::GEDBG_MATRIX, GetHandle(), ContextPoint::FromClient(point))) {
case ID_DISASM_TOGGLEBREAKPOINT:
ToggleBreakpoint(row);
break;
case ID_DISASM_COPYINSTRUCTIONDISASM:
{
float val;
if (GetValue(row, column, val)) {
wchar_t dest[512];
swprintf(dest, 511, L"%f", val);
W32Util::CopyTextToClipboard(GetHandle(), dest);
}
break;
}
case ID_GEDBG_COPYALL:
CopyRows(0, GetRowCount());
break;
case ID_REGLIST_CHANGE:
OnDoubleClick(row, MATRIXLIST_COL_0);
break;
}
}
TabMatrices::TabMatrices(HINSTANCE _hInstance, HWND _hParent)
: Dialog((LPCSTR)IDD_GEDBG_TAB_MATRICES, _hInstance, _hParent) {
values = new CtrlMatrixList(GetDlgItem(m_hDlg, IDC_GEDBG_MATRICES));
+11 -3
View File
@@ -75,9 +75,17 @@ public:
CtrlMatrixList(HWND hwnd);
protected:
virtual bool WindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT& returnValue) { return false; };
virtual void GetColumnText(wchar_t *dest, int row, int col);
virtual int GetRowCount();
bool WindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT &returnValue) override {
return false;
}
void GetColumnText(wchar_t *dest, int row, int col) override;
int GetRowCount() override;
void OnDoubleClick(int row, int column) override;
void OnRightClick(int row, int column, const POINT &point) override;
private:
bool GetValue(int row, int col, float &val);
void ToggleBreakpoint(int row);
};
class TabMatrices : public Dialog {
+1
View File
@@ -30,6 +30,7 @@ enum class ContextMenuID {
DISPLAYLISTVIEW = 6,
GEDBG_STATE = 7,
GEDBG_PREVIEW = 8,
GEDBG_MATRIX = 9,
};
struct ContextPoint {
+9
View File
@@ -779,6 +779,15 @@ BEGIN
MENUITEM "Export Image...", ID_GEDBG_EXPORT_IMAGE
MENUITEM "Show Prim Preview", ID_GEDBG_ENABLE_PREVIEW
END
POPUP "matrixoptions"
BEGIN
MENUITEM "Change...", ID_REGLIST_CHANGE
MENUITEM SEPARATOR
MENUITEM "Copy Value", ID_DISASM_COPYINSTRUCTIONDISASM
MENUITEM "Copy Entire Tab (Formatted)",ID_GEDBG_COPYALL
MENUITEM SEPARATOR
MENUITEM "Toggle Breakpoint", ID_DISASM_TOGGLEBREAKPOINT
END
END
#endif // English (United States) resources