Added support for saving metadata (VPU state) for frame dumps.

git-svn-id: http://svn.purei.org/purei/trunk@1158 b36208d7-6611-0410-8bec-b1987f11c4a2
This commit is contained in:
jpd002 2013-07-07 22:46:30 +00:00
parent 761dcef48e
commit 1b44ad7458
12 changed files with 166 additions and 49 deletions

View File

@ -9,13 +9,16 @@
class CGsPacketMetadata
{
public:
#ifdef DEBUGGER_INCLUDED
explicit CGsPacketMetadata(unsigned int pathIndex = 0)
: pathIndex(pathIndex)
, vuMemPacketAddress(0)
, vpu1Top(0)
, vpu1Itop(0)
{
memset(&vu1State, 0, sizeof(vu1State));
memset(microMem1, 0, sizeof(microMem1));
memset(vuMem1, 0, sizeof(vuMem1));
}
unsigned int pathIndex;
@ -25,6 +28,12 @@ public:
uint32 vpu1Top;
uint32 vpu1Itop;
uint32 vuMemPacketAddress;
#else
explicit CGsPacketMetadata(unsigned int = 0)
{
}
#endif
};
class CGsPacket

View File

@ -5,6 +5,7 @@
#include "Ps2Const.h"
#include "Profiler.h"
#include "Log.h"
#include "FrameDump.h"
#define LOG_NAME ("gif")
@ -166,7 +167,7 @@ uint32 CGIF::ProcessRegList(CGSHandler::RegisterWriteList& writeList, uint8* mem
uint128 packet;
uint32 nRegDesc = (uint32)((m_regList >> (j * 4)) & 0x0F);
packet.nV[0] = *(uint32*)&memory[address + 0x00];
packet.nV[0] = *(uint32*)&memory[address + 0x00];
packet.nV[1] = *(uint32*)&memory[address + 0x04];
address += 0x08;
@ -202,7 +203,7 @@ uint32 CGIF::ProcessImage(uint8* memory, uint32 address, uint32 end)
return (totalLoops * 0x10);
}
uint32 CGIF::ProcessPacket(uint8* memory, uint32 address, uint32 end)
uint32 CGIF::ProcessPacket(uint8* memory, uint32 address, uint32 end, const CGsPacketMetadata& packetMetadata)
{
std::unique_lock<std::mutex> pathLock(m_pathMutex);
static CGSHandler::RegisterWriteList writeList;
@ -212,7 +213,8 @@ uint32 CGIF::ProcessPacket(uint8* memory, uint32 address, uint32 end)
#endif
#ifdef _DEBUG
CLog::GetInstance().Print(LOG_NAME, "Received GIF packet at 0x%0.8X of 0x%0.8X bytes.\r\n", address, end - address);
CLog::GetInstance().Print(LOG_NAME, "Received GIF packet on path %d at 0x%0.8X of 0x%0.8X bytes.\r\n",
packetMetadata.pathIndex, address, end - address);
#endif
writeList.clear();
@ -273,9 +275,9 @@ uint32 CGIF::ProcessPacket(uint8* memory, uint32 address, uint32 end)
}
}
if(m_gs != NULL && !writeList.empty())
if((m_gs != nullptr) && !writeList.empty())
{
m_gs->WriteRegisterMassively(writeList.data(), static_cast<unsigned int>(writeList.size()));
m_gs->WriteRegisterMassively(writeList.data(), static_cast<unsigned int>(writeList.size()), &packetMetadata);
}
#ifdef _DEBUG
@ -311,7 +313,7 @@ uint32 CGIF::ReceiveDMA(uint32 address, uint32 qwc, uint32 unused, bool tagInclu
while(address < end)
{
address += ProcessPacket(memory, address, end);
address += ProcessPacket(memory, address, end, CGsPacketMetadata(3));
}
return qwc;

View File

@ -25,7 +25,7 @@ public:
void Reset();
uint32 ReceiveDMA(uint32, uint32, uint32, bool);
uint32 ProcessPacket(uint8*, uint32, uint32);
uint32 ProcessPacket(uint8*, uint32, uint32, const CGsPacketMetadata&);
private:
uint32 ProcessPacked(CGSHandler::RegisterWriteList&, uint8*, uint32, uint32);

View File

@ -51,6 +51,15 @@
#define LOG_NAME ("gs")
struct MASSIVEWRITE_INFO
{
#ifdef DEBUGGER_INCLUDED
CGsPacketMetadata metadata;
#endif
unsigned int count;
CGSHandler::RegisterWrite writes[1];
};
CGSHandler::CGSHandler()
: m_threadDone(false)
, m_flipMode(FLIP_MODE_SMODE2)
@ -370,11 +379,22 @@ void CGSHandler::FeedImageData(void* data, uint32 length)
m_mailBox.SendCall(std::bind(&CGSHandler::FeedImageDataImpl, this, buffer, length));
}
void CGSHandler::WriteRegisterMassively(const RegisterWrite* writeList, unsigned int count)
void CGSHandler::WriteRegisterMassively(const RegisterWrite* writeList, unsigned int count, const CGsPacketMetadata* metadata)
{
RegisterWrite* writeListCopy = new CGSHandler::RegisterWrite[count];
memcpy(writeListCopy, writeList, sizeof(CGSHandler::RegisterWrite) * count);
m_mailBox.SendCall(bind(&CGSHandler::WriteRegisterMassivelyImpl, this, writeListCopy, count));
auto massiveWrite = reinterpret_cast<MASSIVEWRITE_INFO*>(malloc(sizeof(MASSIVEWRITE_INFO) + (count * sizeof(RegisterWrite))));
memcpy(massiveWrite->writes, writeList, sizeof(CGSHandler::RegisterWrite) * count);
massiveWrite->count = count;
#ifdef DEBUGGER_INCLUDED
if(metadata != nullptr)
{
memcpy(&massiveWrite->metadata, metadata, sizeof(CGsPacketMetadata));
}
else
{
massiveWrite->metadata = CGsPacketMetadata();
}
#endif
m_mailBox.SendCall([=] () { WriteRegisterMassivelyImpl(massiveWrite); });
}
void CGSHandler::WriteRegisterImpl(uint8 nRegister, uint64 nData)
@ -466,22 +486,22 @@ void CGSHandler::FeedImageDataImpl(void* pData, uint32 nLength)
}
}
void CGSHandler::WriteRegisterMassivelyImpl(const RegisterWrite* writeList, unsigned int count)
void CGSHandler::WriteRegisterMassivelyImpl(MASSIVEWRITE_INFO* massiveWrite)
{
#ifdef DEBUGGER_INCLUDED
if(m_frameDump)
{
m_frameDump->AddPacket(writeList, count, nullptr);
m_frameDump->AddPacket(massiveWrite->writes, massiveWrite->count, &massiveWrite->metadata);
}
#endif
const RegisterWrite* writeIterator = writeList;
for(unsigned int i = 0; i < count; i++)
const RegisterWrite* writeIterator = massiveWrite->writes;
for(unsigned int i = 0; i < massiveWrite->count; i++)
{
WriteRegisterImpl(writeIterator->first, writeIterator->second);
writeIterator++;
}
delete [] writeList;
free(massiveWrite);
}
void CGSHandler::BeginTransfer()

View File

@ -12,6 +12,8 @@
#include "Integer64.h"
class CFrameDump;
class CGsPacketMetadata;
struct MASSIVEWRITE_INFO;
#define PREF_CGSHANDLER_FLIPMODE "renderer.flipmode"
#define PREF_CGSHANDLER_PRESENTATION_MODE "renderer.presentationmode"
@ -487,7 +489,7 @@ public:
void WriteRegister(uint8, uint64);
void FeedImageData(void*, uint32);
void WriteRegisterMassively(const RegisterWrite*, unsigned int);
void WriteRegisterMassively(const RegisterWrite*, unsigned int, const CGsPacketMetadata*);
void FetchImagePSMCT16(uint16*, uint32, uint32, uint32, uint32);
void FetchImagePSMCT16S(uint16*, uint32, uint32, uint32, uint32);
@ -607,7 +609,7 @@ protected:
void MarkNewFrame();
virtual void WriteRegisterImpl(uint8, uint64);
virtual void FeedImageDataImpl(void*, uint32);
virtual void WriteRegisterMassivelyImpl(const RegisterWrite*, unsigned int);
virtual void WriteRegisterMassivelyImpl(MASSIVEWRITE_INFO*);
void BeginTransfer();

View File

@ -7,6 +7,7 @@
#include "Ps2Const.h"
#include "RegisterStateFile.h"
#include "Log.h"
#include "FrameDump.h"
#ifdef PROFILE
#define PROFILE_VIFZONE "VIF"
@ -152,9 +153,24 @@ void CVIF::ProcessXGKICK(uint32 nAddress)
nAddress &= 0x3FF;
nAddress *= 0x10;
// assert(nAddress < PS2::VUMEM1SIZE);
// assert(nAddress < PS2::VUMEM1SIZE);
m_gif.ProcessPacket(m_pVPU[1]->GetVuMemory(), nAddress, PS2::VUMEM1SIZE);
CGsPacketMetadata metadata;
#ifdef DEBUGGER_INCLUDED
metadata.pathIndex = 1;
metadata.vuMemPacketAddress = nAddress;
metadata.vpu1Top = m_pVPU[1]->GetVuTopMiniState();
metadata.vpu1Itop = m_pVPU[1]->GetVuItopMiniState();
memcpy(&metadata.vu1State, &m_pVPU[1]->GetVuMiniState(), sizeof(MIPSSTATE));
memcpy(metadata.vuMem1, m_pVPU[1]->GetVuMemoryMiniState(), PS2::VUMEM1SIZE);
memcpy(metadata.microMem1, m_pVPU[1]->GetMicroMemoryMiniState(), PS2::MICROMEM1SIZE);
#endif
m_gif.ProcessPacket(m_pVPU[1]->GetVuMemory(), nAddress, PS2::VUMEM1SIZE, metadata);
#ifdef DEBUGGER_INCLUDED
m_pVPU[1]->SaveMiniState();
#endif
}
void CVIF::StartVu0MicroProgram(uint32 address)

View File

@ -2,6 +2,7 @@
#include "Log.h"
#include "RegisterStateFile.h"
#include <boost/lexical_cast.hpp>
#include "Ps2Const.h"
#define LOG_NAME ("vpu")
@ -27,20 +28,29 @@
#define STATE_REGS_READTICK ("readTick")
#define STATE_REGS_WRITETICK ("writeTick")
CVPU::CVPU(CVIF& vif, unsigned int vpuNumber, const CVIF::VPUINIT& vpuInit) :
m_vif(vif),
m_vpuNumber(vpuNumber),
m_pMicroMem(vpuInit.microMem),
m_pVUMem(vpuInit.vuMem),
m_pCtx(vpuInit.context),
m_executor(*vpuInit.context)
CVPU::CVPU(CVIF& vif, unsigned int vpuNumber, const CVIF::VPUINIT& vpuInit)
: m_vif(vif)
, m_vpuNumber(vpuNumber)
, m_microMem(vpuInit.microMem)
, m_vuMem(vpuInit.vuMem)
, m_ctx(vpuInit.context)
, m_executor(*vpuInit.context)
#ifdef DEBUGGER_INCLUDED
, m_microMemMiniState(new uint8[(vpuNumber == 0) ? PS2::MICROMEM0SIZE : PS2::MICROMEM1SIZE])
, m_vuMemMiniState(new uint8[(vpuNumber == 0) ? PS2::VUMEM0SIZE : PS2::VUMEM1SIZE])
, m_topMiniState(0)
, m_itopMiniState(0)
#endif
{
}
CVPU::~CVPU()
{
#ifdef DEBUGGER_INCLUDED
delete [] m_microMemMiniState;
delete [] m_vuMemMiniState;
#endif
}
void CVPU::Execute(bool singleStep)
@ -48,7 +58,7 @@ void CVPU::Execute(bool singleStep)
unsigned int quota = singleStep ? 1 : 5000;
assert(IsRunning());
m_executor.Execute(quota);
if(m_pCtx->m_State.nHasException)
if(m_ctx->m_State.nHasException)
{
//E bit encountered
m_vif.SetStat(m_vif.GetStat() & ~GetVbs());
@ -67,6 +77,40 @@ void CVPU::DisableBreakpointsOnce()
m_executor.DisableBreakpointsOnce();
}
void CVPU::SaveMiniState()
{
memcpy(m_microMemMiniState, m_microMem, (m_vpuNumber == 0) ? PS2::MICROMEM0SIZE : PS2::MICROMEM1SIZE);
memcpy(m_vuMemMiniState, m_vuMem, (m_vpuNumber == 0) ? PS2::VUMEM0SIZE : PS2::VUMEM1SIZE);
memcpy(&m_vuMiniState, &m_ctx->m_State, sizeof(MIPSSTATE));
m_topMiniState = (m_vpuNumber == 0) ? 0 : GetTOP();
m_itopMiniState = GetITOP();
}
const MIPSSTATE& CVPU::GetVuMiniState() const
{
return m_vuMiniState;
}
uint8* CVPU::GetVuMemoryMiniState() const
{
return m_vuMemMiniState;
}
uint8* CVPU::GetMicroMemoryMiniState() const
{
return m_microMemMiniState;
}
uint32 CVPU::GetVuTopMiniState() const
{
return m_topMiniState;
}
uint32 CVPU::GetVuItopMiniState() const
{
return m_itopMiniState;
}
#endif
void CVPU::Reset()
@ -148,12 +192,12 @@ uint32 CVPU::GetITOP() const
uint8* CVPU::GetVuMemory() const
{
return m_pVUMem;
return m_vuMem;
}
CMIPS& CVPU::GetContext() const
{
return *m_pCtx;
return *m_ctx;
}
void CVPU::ProcessPacket(StreamType& stream)
@ -248,7 +292,7 @@ void CVPU::ExecuteCommand(StreamType& stream, CODE nCommand)
break;
case 0x17:
//MSCNT
StartMicroProgram(m_pCtx->m_State.nPC);
StartMicroProgram(m_ctx->m_State.nPC);
break;
case 0x20:
//STMASK
@ -281,7 +325,6 @@ void CVPU::StartMicroProgram(uint32 address)
}
assert(!m_STAT.nVEW);
ExecuteMicro(address);
}
@ -291,9 +334,13 @@ void CVPU::ExecuteMicro(uint32 nAddress)
CLog::GetInstance().Print(LOG_NAME, "Starting microprogram execution at 0x%0.8X.\r\n", nAddress);
m_pCtx->m_State.nPC = nAddress;
m_pCtx->m_State.pipeTime = 0;
m_pCtx->m_State.nHasException = 0;
m_ctx->m_State.nPC = nAddress;
m_ctx->m_State.pipeTime = 0;
m_ctx->m_State.nHasException = 0;
#ifdef DEBUGGER_INCLUDED
SaveMiniState();
#endif
m_vif.SetStat(m_vif.GetStat() | GetVbs());
@ -332,10 +379,10 @@ void CVPU::Cmd_MPG(StreamType& stream, CODE nCommand)
stream.Read(microProgram, nSize);
//Check if there's a change
if(memcmp(m_pMicroMem + nDstAddr, microProgram, nSize) != 0)
if(memcmp(m_microMem + nDstAddr, microProgram, nSize) != 0)
{
m_executor.ClearActiveBlocks();
memcpy(m_pMicroMem + nDstAddr, microProgram, nSize);
memcpy(m_microMem + nDstAddr, microProgram, nSize);
}
}
@ -444,7 +491,7 @@ void CVPU::Cmd_UNPACK(StreamType& stream, CODE nCommand, uint32 nDstAddr)
nDstAddr *= 0x10;
uint128* dst = reinterpret_cast<uint128*>(&m_pVUMem[nDstAddr]);
uint128* dst = reinterpret_cast<uint128*>(&m_vuMem[nDstAddr]);
while((currentNum != 0) && stream.GetAvailableReadBytes())
{

View File

@ -1,5 +1,4 @@
#ifndef _VPU_H_
#define _VPU_H_
#pragma once
#include "Types.h"
#include "VIF.h"
@ -35,6 +34,13 @@ public:
#ifdef DEBUGGER_INCLUDED
bool MustBreak() const;
void DisableBreakpointsOnce();
void SaveMiniState();
const MIPSSTATE& GetVuMiniState() const;
uint8* GetVuMemoryMiniState() const;
uint8* GetMicroMemoryMiniState() const;
uint32 GetVuTopMiniState() const;
uint32 GetVuItopMiniState() const;
#endif
protected:
@ -136,13 +142,19 @@ protected:
uint128 m_buffer;
uint8* m_pMicroMem;
uint8* m_pVUMem;
CMIPS* m_pCtx;
uint8* m_microMem;
uint8* m_vuMem;
CMIPS* m_ctx;
CVIF& m_vif;
#ifdef DEBUGGER_INCLUDED
MIPSSTATE m_vuMiniState;
uint8* m_microMemMiniState;
uint8* m_vuMemMiniState;
uint32 m_topMiniState;
uint32 m_itopMiniState;
#endif
unsigned int m_vpuNumber;
CVuExecutor m_executor;
};
#endif

View File

@ -1,6 +1,7 @@
#include "VPU1.h"
#include "Ps2Const.h"
#include "RegisterStateFile.h"
#include "FrameDump.h"
#include <boost/lexical_cast.hpp>
#define STATE_PREFIX ("vif/vpu1_")
@ -127,7 +128,7 @@ void CVPU1::Cmd_DIRECT(StreamType& stream, CODE nCommand)
int32 remainingLength = nSize;
while(remainingLength > 0)
{
uint32 processed = m_vif.GetGif().ProcessPacket(packet, 0, remainingLength);
uint32 processed = m_vif.GetGif().ProcessPacket(packet, 0, remainingLength, CGsPacketMetadata(2));
packet += processed;
remainingLength -= processed;
assert(remainingLength >= 0);

View File

@ -203,7 +203,7 @@ void CFrameDebugger::UpdateDisplay(int32 targetCmdIndex)
}
}
m_gs->WriteRegisterMassively(writes.data(), writes.size());
m_gs->WriteRegisterMassively(writes.data(), writes.size(), nullptr);
m_gs->Flip();
UpdateCurrentTab();
@ -268,6 +268,7 @@ void CFrameDebugger::ToggleDepthTest()
void CFrameDebugger::StepVu1()
{
#ifdef DEBUGGER_INCLUDED
if(m_currentMetadata.pathIndex != 1)
{
MessageBeep(-1);
@ -281,4 +282,5 @@ void CFrameDebugger::StepVu1()
}
m_vu1ProgramView->StepVu1();
#endif
}

View File

@ -45,6 +45,8 @@ void CGsRegisterWriteListView::SetFrameDump(CFrameDump* frameDump)
m_packetsTreeView->SetRedraw(false);
#ifdef DEBUGGER_INCLUDED
m_packetInfos.reserve(m_frameDump->GetPackets().size());
uint32 packetIndex = 0, cmdIndex = 0;
@ -77,6 +79,8 @@ void CGsRegisterWriteListView::SetFrameDump(CFrameDump* frameDump)
m_writeInfos.resize(cmdIndex, WRITEINFO());
#endif //DEBUGGER_INCLUDED
m_packetsTreeView->SetRedraw(true);
RedrawWindow(*m_packetsTreeView, nullptr, nullptr, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);

View File

@ -45,12 +45,14 @@ CVu1ProgramView::~CVu1ProgramView()
void CVu1ProgramView::UpdateState(CGSHandler* gs, CGsPacketMetadata* metadata)
{
#ifdef DEBUGGER_INCLUDED
memcpy(m_virtualMachine.GetMicroMem1(), metadata->microMem1, PS2::MICROMEM1SIZE);
memcpy(m_virtualMachine.GetVuMem1(), metadata->vuMem1, PS2::VUMEM1SIZE);
memcpy(&m_virtualMachine.GetVu1Context()->m_State, &metadata->vu1State, sizeof(MIPSSTATE));
m_virtualMachine.SetVpu1Top(metadata->vpu1Top);
m_virtualMachine.SetVpu1Itop(metadata->vpu1Itop);
m_vuMemPacketAddress = metadata->vuMemPacketAddress;
#endif
m_disAsm->Redraw();
m_memoryView->Redraw();