mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-06-02 00:33:16 +00:00
Devtools: PM4 Explorer (#1094)
* Devtools: Pause system * Devtools: pm4 viewer - new menu bar - refactored video_info layer - dump & inspect pm4 packets - removed dumpPM4 config - renamed System to DebugState - add docking space - simple video info constrained to window size * Devtools: pm4 viewer - add combo to select the queue * Devtools: pm4 viewer - add hex editor * Devtools: pm4 viewer - dump current cmd * add monospaced font to devtools * Devtools: pm4 viewer - use spec op name avoid some allocations
This commit is contained in:
parent
009f956d8d
commit
af398e3684
46 changed files with 19323 additions and 242 deletions
102
src/core/debug_state.cpp
Normal file
102
src/core/debug_state.cpp
Normal file
|
@ -0,0 +1,102 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/native_clock.h"
|
||||
#include "common/singleton.h"
|
||||
#include "debug_state.h"
|
||||
#include "libraries/kernel/event_queues.h"
|
||||
#include "libraries/kernel/time_management.h"
|
||||
#include "libraries/system/msgdialog.h"
|
||||
|
||||
using namespace DebugStateType;
|
||||
|
||||
DebugStateImpl& DebugState = *Common::Singleton<DebugStateImpl>::Instance();
|
||||
|
||||
static ThreadID ThisThreadID() {
|
||||
#ifdef _WIN32
|
||||
return GetCurrentThreadId();
|
||||
#else
|
||||
return pthread_self();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void PauseThread(ThreadID id) {
|
||||
#ifdef _WIN32
|
||||
auto handle = OpenThread(THREAD_SUSPEND_RESUME, FALSE, id);
|
||||
SuspendThread(handle);
|
||||
CloseHandle(handle);
|
||||
#else
|
||||
pthread_kill(id, SIGUSR1);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void ResumeThread(ThreadID id) {
|
||||
#ifdef _WIN32
|
||||
auto handle = OpenThread(THREAD_SUSPEND_RESUME, FALSE, id);
|
||||
ResumeThread(handle);
|
||||
CloseHandle(handle);
|
||||
#else
|
||||
pthread_kill(id, SIGUSR1);
|
||||
#endif
|
||||
}
|
||||
|
||||
void DebugStateImpl::AddCurrentThreadToGuestList() {
|
||||
std::lock_guard lock{guest_threads_mutex};
|
||||
const ThreadID id = ThisThreadID();
|
||||
guest_threads.push_back(id);
|
||||
}
|
||||
|
||||
void DebugStateImpl::RemoveCurrentThreadFromGuestList() {
|
||||
std::lock_guard lock{guest_threads_mutex};
|
||||
const ThreadID id = ThisThreadID();
|
||||
std::erase_if(guest_threads, [&](const ThreadID& v) { return v == id; });
|
||||
}
|
||||
|
||||
void DebugStateImpl::PauseGuestThreads() {
|
||||
using namespace Libraries::MsgDialog;
|
||||
std::unique_lock lock{guest_threads_mutex};
|
||||
if (is_guest_threads_paused) {
|
||||
return;
|
||||
}
|
||||
if (ShouldPauseInSubmit()) {
|
||||
waiting_submit_pause = false;
|
||||
should_show_frame_dump = true;
|
||||
}
|
||||
bool self_guest = false;
|
||||
ThreadID self_id = ThisThreadID();
|
||||
for (const auto& id : guest_threads) {
|
||||
if (id == self_id) {
|
||||
self_guest = true;
|
||||
} else {
|
||||
PauseThread(id);
|
||||
}
|
||||
}
|
||||
pause_time = Libraries::Kernel::Dev::GetClock()->GetUptime();
|
||||
is_guest_threads_paused = true;
|
||||
lock.unlock();
|
||||
if (self_guest) {
|
||||
PauseThread(self_id);
|
||||
}
|
||||
}
|
||||
|
||||
void DebugStateImpl::ResumeGuestThreads() {
|
||||
std::lock_guard lock{guest_threads_mutex};
|
||||
if (!is_guest_threads_paused) {
|
||||
return;
|
||||
}
|
||||
|
||||
u64 delta_time = Libraries::Kernel::Dev::GetClock()->GetUptime() - pause_time;
|
||||
Libraries::Kernel::Dev::GetInitialPtc() += delta_time;
|
||||
for (const auto& id : guest_threads) {
|
||||
ResumeThread(id);
|
||||
}
|
||||
is_guest_threads_paused = false;
|
||||
}
|
||||
|
||||
void DebugStateImpl::RequestFrameDump(s32 count) {
|
||||
gnm_frame_dump_request_count = count;
|
||||
frame_dump_list.clear();
|
||||
frame_dump_list.resize(count);
|
||||
waiting_submit_pause = true;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue