mirror of
https://github.com/jpd002/Play-.git
synced 2025-04-28 21:57:57 +03:00
Move all frame dumping logic in GS handler.
Fixes a bunch of incomplete dump issues, race conditions and potential crashes.
This commit is contained in:
parent
d5208b7322
commit
97cf4123b9
5 changed files with 54 additions and 76 deletions
|
@ -324,19 +324,6 @@ std::future<bool> CPS2VM::LoadState(const fs::path& statePath)
|
|||
return future;
|
||||
}
|
||||
|
||||
void CPS2VM::TriggerFrameDump(const FrameDumpCallback& frameDumpCallback)
|
||||
{
|
||||
#ifdef DEBUGGER_INCLUDED
|
||||
m_mailBox.SendCall(
|
||||
[=]() {
|
||||
std::unique_lock<std::mutex> frameDumpCallbackMutexLock(m_frameDumpCallbackMutex);
|
||||
if(m_frameDumpCallback) return;
|
||||
m_frameDumpCallback = frameDumpCallback;
|
||||
},
|
||||
false);
|
||||
#endif
|
||||
}
|
||||
|
||||
CPS2VM::CPU_UTILISATION_INFO CPS2VM::GetCpuUtilisationInfo() const
|
||||
{
|
||||
return m_cpuUtilisation;
|
||||
|
@ -633,7 +620,6 @@ void CPS2VM::CreateGsHandlerImpl(const CGSHandler::FactoryFunction& factoryFunct
|
|||
gs->Release();
|
||||
delete gs;
|
||||
}
|
||||
m_OnNewFrameConnection = m_ee->m_gs->OnNewFrame.Connect(std::bind(&CPS2VM::OnGsNewFrame, this));
|
||||
}
|
||||
|
||||
void CPS2VM::DestroyGsHandlerImpl()
|
||||
|
@ -679,26 +665,6 @@ void CPS2VM::DestroySoundHandlerImpl()
|
|||
m_soundHandler = nullptr;
|
||||
}
|
||||
|
||||
void CPS2VM::OnGsNewFrame()
|
||||
{
|
||||
#ifdef DEBUGGER_INCLUDED
|
||||
std::unique_lock<std::mutex> dumpFrameCallbackMutexLock(m_frameDumpCallbackMutex);
|
||||
if(m_dumpingFrame && !m_frameDump.GetPackets().empty())
|
||||
{
|
||||
m_ee->m_gs->EndFrameDump();
|
||||
m_frameDumpCallback(m_frameDump);
|
||||
m_dumpingFrame = false;
|
||||
m_frameDumpCallback = FrameDumpCallback();
|
||||
}
|
||||
else if(m_frameDumpCallback)
|
||||
{
|
||||
m_frameDump.Reset();
|
||||
m_ee->m_gs->BeginFrameDump(&m_frameDump);
|
||||
m_dumpingFrame = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CPS2VM::UpdateEe()
|
||||
{
|
||||
#ifdef PROFILE
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "ee/Ee_SubSystem.h"
|
||||
#include "iop/Iop_SubSystem.h"
|
||||
#include "../tools/PsfPlayer/Source/SoundHandler.h"
|
||||
#include "FrameDump.h"
|
||||
#include "FrameLimiter.h"
|
||||
#include "Profiler.h"
|
||||
|
||||
|
@ -32,7 +31,6 @@ public:
|
|||
typedef std::unique_ptr<COpticalMedia> OpticalMediaPtr;
|
||||
typedef std::unique_ptr<Ee::CSubSystem> EeSubSystemPtr;
|
||||
typedef std::unique_ptr<Iop::CSubSystem> IopSubSystemPtr;
|
||||
typedef std::function<void(const CFrameDump&)> FrameDumpCallback;
|
||||
typedef Framework::CSignal<void(const CProfiler::ZoneArray&)> ProfileFrameDoneSignal;
|
||||
typedef std::function<void(CPS2VM*)> ExecutableReloadedHandler;
|
||||
|
||||
|
@ -79,8 +77,6 @@ public:
|
|||
std::future<bool> SaveState(const fs::path&);
|
||||
std::future<bool> LoadState(const fs::path&);
|
||||
|
||||
void TriggerFrameDump(const FrameDumpCallback&);
|
||||
|
||||
CPU_UTILISATION_INFO GetCpuUtilisationInfo() const;
|
||||
|
||||
#ifdef DEBUGGER_INCLUDED
|
||||
|
@ -142,8 +138,6 @@ private:
|
|||
void UpdateIop();
|
||||
void UpdateSpu();
|
||||
|
||||
void OnGsNewFrame();
|
||||
|
||||
void SetIopOpticalMedia(COpticalMedia*);
|
||||
|
||||
void RegisterModulesInPadHandler();
|
||||
|
@ -179,13 +173,6 @@ private:
|
|||
bool m_singleStepVu0 = false;
|
||||
bool m_singleStepVu1 = false;
|
||||
|
||||
#ifdef DEBUGGER_INCLUDED
|
||||
CFrameDump m_frameDump;
|
||||
FrameDumpCallback m_frameDumpCallback;
|
||||
std::mutex m_frameDumpCallbackMutex;
|
||||
bool m_dumpingFrame = false;
|
||||
#endif
|
||||
|
||||
//SPU update parameters
|
||||
enum
|
||||
{
|
||||
|
@ -211,5 +198,4 @@ private:
|
|||
|
||||
CPS2OS::RequestLoadExecutableEvent::Connection m_OnRequestLoadExecutableConnection;
|
||||
Framework::CSignal<void()>::Connection m_OnCrtModeChangeConnection;
|
||||
Framework::CSignal<void(uint32)>::Connection m_OnNewFrameConnection;
|
||||
};
|
||||
|
|
|
@ -336,22 +336,38 @@ void CGSHandler::Copy(CGSHandler* source)
|
|||
SendGSCall([&]() { WriteBackMemoryCache(); });
|
||||
}
|
||||
|
||||
void CGSHandler::BeginFrameDump(CFrameDump* frameDump)
|
||||
void CGSHandler::TriggerFrameDump(const FrameDumpCallback& frameDumpCallback)
|
||||
{
|
||||
m_frameDump = frameDump;
|
||||
|
||||
//This is expected to be called from the GS thread
|
||||
SyncMemoryCache();
|
||||
|
||||
memcpy(m_frameDump->GetInitialGsRam(), GetRam(), RAMSIZE);
|
||||
memcpy(m_frameDump->GetInitialGsRegisters(), GetRegisters(), CGSHandler::REGISTER_MAX * sizeof(uint64));
|
||||
m_frameDump->SetInitialSMODE2(GetSMODE2());
|
||||
#ifdef DEBUGGER_INCLUDED
|
||||
m_mailBox.SendCall(
|
||||
[=]() {
|
||||
if(m_frameDumpCallback) return;
|
||||
m_frameDumpCallback = frameDumpCallback;
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
void CGSHandler::EndFrameDump()
|
||||
void CGSHandler::UpdateFrameDumpState()
|
||||
{
|
||||
assert(m_frameDump);
|
||||
m_frameDump = nullptr;
|
||||
#ifdef DEBUGGER_INCLUDED
|
||||
if(m_frameDump && !m_frameDump->GetPackets().empty())
|
||||
{
|
||||
m_frameDumpCallback(*m_frameDump.get());
|
||||
m_frameDumpCallback = FrameDumpCallback();
|
||||
m_frameDump.reset();
|
||||
}
|
||||
else if(m_frameDumpCallback)
|
||||
{
|
||||
m_frameDump = std::make_unique<CFrameDump>();
|
||||
|
||||
//This is expected to be called from the GS thread
|
||||
SyncMemoryCache();
|
||||
|
||||
memcpy(m_frameDump->GetInitialGsRam(), GetRam(), RAMSIZE);
|
||||
memcpy(m_frameDump->GetInitialGsRegisters(), GetRegisters(), CGSHandler::REGISTER_MAX * sizeof(uint64));
|
||||
m_frameDump->SetInitialSMODE2(GetSMODE2());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CGSHandler::InitFromFrameDump(CFrameDump* frameDump)
|
||||
|
@ -570,6 +586,7 @@ void CGSHandler::MarkNewFrame()
|
|||
{
|
||||
OnNewFrame(m_drawCallCount);
|
||||
m_drawCallCount = 0;
|
||||
UpdateFrameDumpState();
|
||||
#ifdef _DEBUG
|
||||
CLog::GetInstance().Print(LOG_NAME, "Frame Done.\r\n---------------------------------------------------------------------------------\r\n");
|
||||
#endif
|
||||
|
@ -614,14 +631,14 @@ void CGSHandler::FeedImageData(const void* data, uint32 length)
|
|||
|
||||
std::vector<uint8> imageData(length + 0x10);
|
||||
memcpy(imageData.data(), data, length);
|
||||
#ifdef DEBUGGER_INCLUDED
|
||||
if(m_frameDump)
|
||||
{
|
||||
m_frameDump->AddImagePacket(imageData.data(), length);
|
||||
}
|
||||
#endif
|
||||
SendGSCall(
|
||||
[this, imageData = std::move(imageData), length]() {
|
||||
#ifdef DEBUGGER_INCLUDED
|
||||
if(m_frameDump)
|
||||
{
|
||||
m_frameDump->AddImagePacket(imageData.data(), length);
|
||||
}
|
||||
#endif
|
||||
FeedImageDataImpl(imageData.data(), length);
|
||||
});
|
||||
}
|
||||
|
@ -638,13 +655,18 @@ void CGSHandler::ProcessWriteBuffer(const CGsPacketMetadata* metadata)
|
|||
assert(m_writeBufferProcessIndex <= m_writeBufferSize);
|
||||
assert(m_writeBufferSubmitIndex <= m_writeBufferProcessIndex);
|
||||
#ifdef DEBUGGER_INCLUDED
|
||||
if(m_frameDump)
|
||||
if(uint32 packetSize = m_writeBufferSize - m_writeBufferProcessIndex; packetSize != 0)
|
||||
{
|
||||
uint32 packetSize = m_writeBufferSize - m_writeBufferProcessIndex;
|
||||
if(packetSize != 0)
|
||||
{
|
||||
m_frameDump->AddRegisterPacket(m_currentWriteBuffer + m_writeBufferProcessIndex, packetSize, metadata);
|
||||
}
|
||||
SendGSCall(
|
||||
[this,
|
||||
packet = m_currentWriteBuffer + m_writeBufferProcessIndex,
|
||||
packetSize,
|
||||
metadata = metadata ? *metadata : CGsPacketMetadata()]() {
|
||||
if(m_frameDump)
|
||||
{
|
||||
m_frameDump->AddRegisterPacket(packet, packetSize, &metadata);
|
||||
}
|
||||
});
|
||||
}
|
||||
#endif
|
||||
for(uint32 writeIndex = m_writeBufferProcessIndex; writeIndex < m_writeBufferSize; writeIndex++)
|
||||
|
|
|
@ -813,6 +813,8 @@ public:
|
|||
typedef std::vector<RegisterWrite> RegisterWriteList;
|
||||
typedef std::function<CGSHandler*(void)> FactoryFunction;
|
||||
|
||||
typedef std::function<void(const CFrameDump&)> FrameDumpCallback;
|
||||
|
||||
typedef Framework::CSignal<void()> FlipCompleteEvent;
|
||||
typedef Framework::CSignal<void(uint32)> NewFrameEvent;
|
||||
|
||||
|
@ -831,8 +833,7 @@ public:
|
|||
virtual void LoadState(Framework::CZipArchiveReader&);
|
||||
void Copy(CGSHandler*);
|
||||
|
||||
void BeginFrameDump(CFrameDump*);
|
||||
void EndFrameDump();
|
||||
void TriggerFrameDump(const FrameDumpCallback&);
|
||||
|
||||
void InitFromFrameDump(CFrameDump*);
|
||||
|
||||
|
@ -1042,6 +1043,8 @@ protected:
|
|||
void ReadImageDataImpl(void*, uint32);
|
||||
void SubmitWriteBufferImpl(const RegisterWrite*, const RegisterWrite*);
|
||||
|
||||
void UpdateFrameDumpState();
|
||||
|
||||
void BeginTransfer();
|
||||
|
||||
virtual void BeginTransferWrite();
|
||||
|
@ -1124,7 +1127,8 @@ protected:
|
|||
#endif
|
||||
std::atomic<int> m_framesInFlight;
|
||||
bool m_threadDone = false;
|
||||
CFrameDump* m_frameDump = nullptr;
|
||||
std::unique_ptr<CFrameDump> m_frameDump;
|
||||
FrameDumpCallback m_frameDumpCallback;
|
||||
bool m_regsDirty = false;
|
||||
bool m_drawEnabled = true;
|
||||
CINTC* m_intc = nullptr;
|
||||
|
|
|
@ -962,7 +962,7 @@ fs::path MainWindow::GetFrameDumpDirectoryPath()
|
|||
|
||||
void MainWindow::DumpNextFrame()
|
||||
{
|
||||
m_virtualMachine->TriggerFrameDump(
|
||||
m_virtualMachine->m_ee->m_gs->TriggerFrameDump(
|
||||
[&](const CFrameDump& frameDump) {
|
||||
try
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue