rsx: Implement draw call stepping

This commit is contained in:
Eladash 2022-12-10 10:57:05 +02:00 committed by Megamouse
parent 40406bd3fe
commit 151a0955cf
5 changed files with 64 additions and 39 deletions

View File

@ -690,6 +690,7 @@ namespace rsx
public: public:
atomic_t<bool> sync_point_request = false; atomic_t<bool> sync_point_request = false;
atomic_t<bool> pause_on_draw = false;
bool in_begin_end = false; bool in_begin_end = false;
std::queue<desync_fifo_cmd_info> recovered_fifo_cmds_history; std::queue<desync_fifo_cmd_info> recovered_fifo_cmds_history;

View File

@ -657,6 +657,13 @@ namespace rsx
{ {
rsxthr->in_begin_end = false; rsxthr->in_begin_end = false;
} }
if (rsxthr->pause_on_draw && rsxthr->pause_on_draw.exchange(false))
{
rsxthr->state -= cpu_flag::dbg_step;
rsxthr->state += cpu_flag::dbg_pause;
rsxthr->check_state();
}
} }
vm::addr_t get_report_data_impl(u32 offset) vm::addr_t get_report_data_impl(u32 offset)

View File

@ -166,42 +166,7 @@ debugger_frame::debugger_frame(std::shared_ptr<gui_settings> gui_settings, QWidg
connect(m_btn_step, &QAbstractButton::clicked, this, &debugger_frame::DoStep); connect(m_btn_step, &QAbstractButton::clicked, this, &debugger_frame::DoStep);
connect(m_btn_step_over, &QAbstractButton::clicked, [this]() { DoStep(true); }); connect(m_btn_step_over, &QAbstractButton::clicked, [this]() { DoStep(true); });
connect(m_btn_run, &QAbstractButton::clicked, [this]() connect(m_btn_run, &QAbstractButton::clicked, this, &debugger_frame::RunBtnPress);
{
if (const auto cpu = get_cpu())
{
// If paused, unpause.
// If not paused, add dbg_pause.
const auto old = cpu->state.fetch_op([](bs_t<cpu_flag>& state)
{
if (state & s_pause_flags)
{
state -= s_pause_flags;
}
else
{
state += cpu_flag::dbg_pause;
}
});
// Notify only if no pause flags are set after this change
if (old & s_pause_flags)
{
if (g_debugger_pause_all_threads_on_bp && Emu.IsPaused() && (old & s_pause_flags) == s_pause_flags)
{
// Resume all threads were paused by this breakpoint
Emu.Resume();
}
cpu->state.notify_one(s_pause_flags);
m_debugger_list->EnableThreadFollowing();
}
}
// Tighten up, put the debugger on a wary watch over any thread info changes if there aren't any
// This allows responsive debugger interaction
m_ui_fast_update_permission_deadline = m_ui_update_ctr + 5;
});
connect(m_choice_units->lineEdit(), &QLineEdit::editingFinished, [&] connect(m_choice_units->lineEdit(), &QLineEdit::editingFinished, [&]
{ {
@ -1156,6 +1121,20 @@ void debugger_frame::DoStep(bool step_over)
m_debugger_list->ShowAddress(cpu->get_pc() + 4, false); m_debugger_list->ShowAddress(cpu->get_pc() + 4, false);
} }
if (step_over && cpu->id_type() == 0x55)
{
const bool was_paused = cpu->is_paused();
static_cast<rsx::thread*>(cpu)->pause_on_draw = true;
if (was_paused)
{
RunBtnPress();
m_debugger_list->EnableThreadFollowing(true);
}
return;
}
if (const auto _state = +cpu->state; _state & s_pause_flags && _state & cpu_flag::wait && !(_state & cpu_flag::dbg_step)) if (const auto _state = +cpu->state; _state & s_pause_flags && _state & cpu_flag::wait && !(_state & cpu_flag::dbg_step))
{ {
if (should_step_over) if (should_step_over)
@ -1166,7 +1145,7 @@ void debugger_frame::DoStep(bool step_over)
const u32 next_instruction_pc = current_instruction_pc + 4; const u32 next_instruction_pc = current_instruction_pc + 4;
m_ppu_breakpoint_handler->AddBreakpoint(next_instruction_pc); m_ppu_breakpoint_handler->AddBreakpoint(next_instruction_pc);
// Undefine previous step over breakpoint if it hasnt been already // Undefine previous step over breakpoint if it hasn't been already
// This can happen when the user steps over a branch that doesn't return to itself // This can happen when the user steps over a branch that doesn't return to itself
if (m_last_step_over_breakpoint != umax) if (m_last_step_over_breakpoint != umax)
{ {
@ -1204,6 +1183,43 @@ void debugger_frame::EnableUpdateTimer(bool enable) const
enable ? m_update->start(10) : m_update->stop(); enable ? m_update->start(10) : m_update->stop();
} }
void debugger_frame::RunBtnPress()
{
if (const auto cpu = get_cpu())
{
// If paused, unpause.
// If not paused, add dbg_pause.
const auto old = cpu->state.fetch_op([](bs_t<cpu_flag>& state)
{
if (state & s_pause_flags)
{
state -= s_pause_flags;
}
else
{
state += cpu_flag::dbg_pause;
}
});
// Notify only if no pause flags are set after this change
if (old & s_pause_flags)
{
if (g_debugger_pause_all_threads_on_bp && Emu.IsPaused() && (old & s_pause_flags) == s_pause_flags)
{
// Resume all threads were paused by this breakpoint
Emu.Resume();
}
cpu->state.notify_one(s_pause_flags);
m_debugger_list->EnableThreadFollowing();
}
}
// Tighten up, put the debugger on a wary watch over any thread info changes if there aren't any
// This allows responsive debugger interaction
m_ui_fast_update_permission_deadline = m_ui_update_ctr + 5;
}
void debugger_frame::EnableButtons(bool enable) void debugger_frame::EnableButtons(bool enable)
{ {
const auto cpu = get_cpu(); const auto cpu = get_cpu();

View File

@ -115,6 +115,7 @@ private Q_SLOTS:
void OnSelectUnit(); void OnSelectUnit();
void ShowPC(bool user_requested = false); void ShowPC(bool user_requested = false);
void EnableUpdateTimer(bool enable) const; void EnableUpdateTimer(bool enable) const;
void RunBtnPress();
}; };
Q_DECLARE_METATYPE(u32) Q_DECLARE_METATYPE(u32)

View File

@ -400,8 +400,8 @@ void Buffer::ShowContextMenu(const QPoint& pos)
} }
}); });
contextMenu.addAction(&action); context_menu.addAction(&action);
contextMenu.exec(mapToGlobal(pos)); context_menu.exec(mapToGlobal(pos));
} }
namespace namespace