mirror of https://github.com/PCSX2/pcsx2.git
GS: Use single array for dump packets
This commit is contained in:
parent
6a15d46461
commit
16cfde0538
|
@ -114,11 +114,11 @@ bool GSDumpFile::GetPreviewImageFromDump(const char* filename, u32* width, u32*
|
|||
bool GSDumpFile::ReadFile()
|
||||
{
|
||||
u32 ss;
|
||||
if (!Read(&m_crc, 4) || !Read(&ss, 4))
|
||||
if (Read(&m_crc, sizeof(m_crc)) != sizeof(m_crc) || Read(&ss, sizeof(ss)) != sizeof(ss))
|
||||
return false;
|
||||
|
||||
m_state_data.resize(ss);
|
||||
if (!Read(m_state_data.data(), ss))
|
||||
if (Read(m_state_data.data(), ss) != ss)
|
||||
return false;
|
||||
|
||||
// Pull serial out of new header, if present.
|
||||
|
@ -149,34 +149,68 @@ bool GSDumpFile::ReadFile()
|
|||
|
||||
// Read the real state data
|
||||
m_state_data.resize(header.state_size);
|
||||
if (!Read(m_state_data.data(), header.state_size))
|
||||
if (Read(m_state_data.data(), header.state_size) != header.state_size)
|
||||
return false;
|
||||
}
|
||||
|
||||
m_regs_data.resize(8192);
|
||||
if (!Read(m_regs_data.data(), m_regs_data.size()))
|
||||
if (Read(m_regs_data.data(), m_regs_data.size()) != m_regs_data.size())
|
||||
return false;
|
||||
|
||||
// read all the packet data in
|
||||
// TODO: make this suck less by getting the full/extracted size and preallocating
|
||||
for (;;)
|
||||
{
|
||||
GSData packet;
|
||||
packet.path = GSTransferPath::Dummy;
|
||||
if (!Read(&packet.id, 1))
|
||||
{
|
||||
if (IsEof())
|
||||
break;
|
||||
const size_t packet_data_size = m_packet_data.size();
|
||||
m_packet_data.resize(std::max<size_t>(packet_data_size * 2, 8 * _1mb));
|
||||
|
||||
return false;
|
||||
const size_t read_size = m_packet_data.size() - packet_data_size;
|
||||
const size_t read = Read(m_packet_data.data() + packet_data_size, read_size);
|
||||
if (read != read_size)
|
||||
{
|
||||
if (!IsEof())
|
||||
return false;
|
||||
|
||||
m_packet_data.resize(packet_data_size + read);
|
||||
m_packet_data.shrink_to_fit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
u8* data = m_packet_data.data();
|
||||
size_t remaining = m_packet_data.size();
|
||||
|
||||
#define GET_BYTE(dst) \
|
||||
do \
|
||||
{ \
|
||||
if (remaining < sizeof(u8)) \
|
||||
return false; \
|
||||
std::memcpy(dst, data, sizeof(u8)); \
|
||||
data++; \
|
||||
remaining--; \
|
||||
} while (0)
|
||||
#define GET_WORD(dst) \
|
||||
do \
|
||||
{ \
|
||||
if (remaining < sizeof(u32)) \
|
||||
return false; \
|
||||
std::memcpy(dst, data, sizeof(u32)); \
|
||||
data += sizeof(u32); \
|
||||
remaining -= sizeof(u32); \
|
||||
} while (0)
|
||||
|
||||
while (remaining > 0)
|
||||
{
|
||||
GSData packet = {};
|
||||
packet.path = GSTransferPath::Dummy;
|
||||
GET_BYTE(&packet.id);
|
||||
|
||||
switch (packet.id)
|
||||
{
|
||||
case GSType::Transfer:
|
||||
{
|
||||
if (!Read(&packet.path, 1) || !Read(&packet.length, 4))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
GET_BYTE(&packet.path);
|
||||
GET_WORD(&packet.length);
|
||||
break;
|
||||
case GSType::VSync:
|
||||
packet.length = 1;
|
||||
break;
|
||||
|
@ -186,18 +220,26 @@ bool GSDumpFile::ReadFile()
|
|||
case GSType::Registers:
|
||||
packet.length = 8192;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (packet.length > 0)
|
||||
{
|
||||
packet.data = std::unique_ptr<u8[]>(new u8[packet.length]);
|
||||
if (!Read(packet.data.get(), packet.length))
|
||||
if (remaining < packet.length)
|
||||
return false;
|
||||
|
||||
packet.data = data;
|
||||
data += packet.length;
|
||||
remaining -= packet.length;
|
||||
}
|
||||
|
||||
m_dump_packets.push_back(std::move(packet));
|
||||
}
|
||||
|
||||
#undef GET_WORD
|
||||
#undef GET_BYTE
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -275,7 +317,7 @@ bool GSDumpLzma::IsEof()
|
|||
return feof(m_fp) && m_avail == 0 && m_strm.avail_in == 0;
|
||||
}
|
||||
|
||||
bool GSDumpLzma::Read(void* ptr, size_t size)
|
||||
size_t GSDumpLzma::Read(void* ptr, size_t size)
|
||||
{
|
||||
size_t off = 0;
|
||||
uint8_t* dst = (uint8_t*)ptr;
|
||||
|
@ -295,13 +337,10 @@ bool GSDumpLzma::Read(void* ptr, size_t size)
|
|||
off += l;
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
Repack(ptr, full_size);
|
||||
return true;
|
||||
}
|
||||
if (off > 0)
|
||||
Repack(ptr, off);
|
||||
|
||||
return false;
|
||||
return off;
|
||||
}
|
||||
|
||||
GSDumpLzma::~GSDumpLzma()
|
||||
|
@ -326,20 +365,17 @@ bool GSDumpRaw::IsEof()
|
|||
return !!feof(m_fp);
|
||||
}
|
||||
|
||||
bool GSDumpRaw::Read(void* ptr, size_t size)
|
||||
size_t GSDumpRaw::Read(void* ptr, size_t size)
|
||||
{
|
||||
size_t ret = fread(ptr, 1, size, m_fp);
|
||||
if (ret != size && ferror(m_fp))
|
||||
{
|
||||
fprintf(stderr, "GSDumpRaw:: Read error (%zu/%zu)\n", ret, size);
|
||||
return false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ret == size)
|
||||
{
|
||||
Repack(ptr, size);
|
||||
return true;
|
||||
}
|
||||
if (ret > 0)
|
||||
Repack(ptr, ret);
|
||||
|
||||
return false;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -291,7 +291,7 @@ public:
|
|||
struct GSData
|
||||
{
|
||||
GSDumpTypes::GSType id;
|
||||
std::unique_ptr<u8[]> data;
|
||||
const u8* data;
|
||||
s32 length;
|
||||
GSDumpTypes::GSTransferPath path;
|
||||
};
|
||||
|
@ -317,7 +317,7 @@ protected:
|
|||
GSDumpFile(FILE* file, FILE* repack_file);
|
||||
|
||||
virtual bool IsEof() = 0;
|
||||
virtual bool Read(void* ptr, size_t size) = 0;
|
||||
virtual size_t Read(void* ptr, size_t size) = 0;
|
||||
|
||||
void Repack(void* ptr, size_t size);
|
||||
|
||||
|
@ -331,9 +331,8 @@ private:
|
|||
|
||||
std::vector<u8> m_regs_data;
|
||||
std::vector<u8> m_state_data;
|
||||
std::vector<u8> m_packet_data;
|
||||
|
||||
// TODO: Allocate a single, large buffer, and store pointers to
|
||||
// each packet instead of a buffer per packet.
|
||||
GSDataArray m_dump_packets;
|
||||
};
|
||||
|
||||
|
@ -356,7 +355,7 @@ public:
|
|||
virtual ~GSDumpLzma();
|
||||
|
||||
bool IsEof() final;
|
||||
bool Read(void* ptr, size_t size) final;
|
||||
size_t Read(void* ptr, size_t size) final;
|
||||
};
|
||||
|
||||
class GSDumpRaw : public GSDumpFile
|
||||
|
@ -366,5 +365,5 @@ public:
|
|||
virtual ~GSDumpRaw() = default;
|
||||
|
||||
bool IsEof() final;
|
||||
bool Read(void* ptr, size_t size) final;
|
||||
size_t Read(void* ptr, size_t size) final;
|
||||
};
|
||||
|
|
|
@ -225,7 +225,7 @@ void GSDumpReplayerCpuStep()
|
|||
{
|
||||
std::unique_ptr<u8[]> data(new u8[16384]);
|
||||
const s32 addr = 16384 - packet.length;
|
||||
std::memcpy(data.get(), packet.data.get() + addr, packet.length);
|
||||
std::memcpy(data.get(), packet.data + addr, packet.length);
|
||||
GSDumpReplayerSendPacketToMTGS(GIF_PATH_1, data.get(), packet.length);
|
||||
}
|
||||
break;
|
||||
|
@ -235,7 +235,7 @@ void GSDumpReplayerCpuStep()
|
|||
case GSDumpTypes::GSTransferPath::Path3:
|
||||
{
|
||||
GSDumpReplayerSendPacketToMTGS(static_cast<GIF_PATH>(static_cast<u8>(packet.path) - 1),
|
||||
reinterpret_cast<const u8*>(packet.data.get()), packet.length);
|
||||
packet.data, packet.length);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -258,14 +258,14 @@ void GSDumpReplayerCpuStep()
|
|||
|
||||
case GSDumpTypes::GSType::ReadFIFO2:
|
||||
{
|
||||
std::unique_ptr<char[]> arr(new char[*((int*)packet.data.get())]);
|
||||
GSreadFIFO2((u8*)arr.get(), *((int*)packet.data.get()));
|
||||
std::unique_ptr<char[]> arr(new char[*((int*)packet.data)]);
|
||||
GSreadFIFO2((u8*)arr.get(), *((int*)packet.data));
|
||||
}
|
||||
break;
|
||||
|
||||
case GSDumpTypes::GSType::Registers:
|
||||
{
|
||||
std::memcpy(PS2MEM_GS, packet.data.get(), std::min<s32>(packet.length, Ps2MemSize::GSregs));
|
||||
std::memcpy(PS2MEM_GS, packet.data, std::min<s32>(packet.length, Ps2MemSize::GSregs));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -433,7 +433,7 @@ void Dialogs::GSDumpDialog::GenPacketInfo(const GSDumpFile::GSData& dump)
|
|||
{
|
||||
case GSType::Transfer:
|
||||
{
|
||||
u8* data = dump.data.get();
|
||||
const u8* data = dump.data;
|
||||
u32 remaining = dump.length;
|
||||
int idx = 0;
|
||||
while (remaining >= 16)
|
||||
|
@ -468,7 +468,7 @@ void Dialogs::GSDumpDialog::GenPacketInfo(const GSDumpFile::GSData& dump)
|
|||
}
|
||||
}
|
||||
|
||||
void Dialogs::GSDumpDialog::ParseTransfer(wxTreeItemId& trootId, u8* data)
|
||||
void Dialogs::GSDumpDialog::ParseTransfer(wxTreeItemId& trootId, const u8* data)
|
||||
{
|
||||
u64 tag = *(u64*)data;
|
||||
u64 regs = *(u64*)(data + 8);
|
||||
|
@ -746,18 +746,18 @@ void Dialogs::GSDumpDialog::ProcessDumpEvent(const GSDumpFile::GSData& event, u8
|
|||
{
|
||||
std::unique_ptr<char[]> data(new char[16384]);
|
||||
int addr = 16384 - event.length;
|
||||
memcpy(data.get(), event.data.get() + addr, event.length);
|
||||
memcpy(data.get(), event.data + addr, event.length);
|
||||
GSgifTransfer1((u8*)data.get(), addr);
|
||||
break;
|
||||
}
|
||||
case GSTransferPath::Path1New:
|
||||
GSgifTransfer((u8*)event.data.get(), event.length / 16);
|
||||
GSgifTransfer((u8*)event.data, event.length / 16);
|
||||
break;
|
||||
case GSTransferPath::Path2:
|
||||
GSgifTransfer2((u8*)event.data.get(), event.length / 16);
|
||||
GSgifTransfer2((u8*)event.data, event.length / 16);
|
||||
break;
|
||||
case GSTransferPath::Path3:
|
||||
GSgifTransfer3((u8*)event.data.get(), event.length / 16);
|
||||
GSgifTransfer3((u8*)event.data, event.length / 16);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -772,12 +772,12 @@ void Dialogs::GSDumpDialog::ProcessDumpEvent(const GSDumpFile::GSData& event, u8
|
|||
}
|
||||
case GSType::ReadFIFO2:
|
||||
{
|
||||
std::unique_ptr<char[]> arr(new char[*((int*)event.data.get())]);
|
||||
GSreadFIFO2((u8*)arr.get(), *((int*)event.data.get()));
|
||||
std::unique_ptr<char[]> arr(new char[*((int*)event.data)]);
|
||||
GSreadFIFO2((u8*)arr.get(), *((int*)event.data));
|
||||
break;
|
||||
}
|
||||
case GSType::Registers:
|
||||
memcpy(regs, event.data.get(), 8192);
|
||||
memcpy(regs, event.data, 8192);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -145,7 +145,7 @@ namespace Dialogs
|
|||
u32 ReadPacketSize(const void* packet);
|
||||
void GenPacketList();
|
||||
void GenPacketInfo(const GSDumpFile::GSData& dump);
|
||||
void ParseTransfer(wxTreeItemId& id, u8* data);
|
||||
void ParseTransfer(wxTreeItemId& id, const u8* data);
|
||||
void ParseTreeReg(wxTreeItemId& id, GSDumpTypes::GIFReg reg, u128 data, bool packed);
|
||||
void ParseTreePrim(wxTreeItemId& id, u32 prim);
|
||||
void CloseDump(wxCommandEvent& event);
|
||||
|
|
Loading…
Reference in New Issue