GPU: Fix playback of VRAM updates during draws

This commit is contained in:
Stenzek 2025-01-17 13:22:40 +10:00
parent bf7ca1951e
commit 3be4f1983d
No known key found for this signature in database

View File

@ -2103,8 +2103,7 @@ void GPU::StopRecordingGPUDump()
Host::AddIconOSDMessage(
osd_key, ICON_EMOJI_CAMERA_WITH_FLASH,
fmt::format(TRANSLATE_FS("GPU", "Compressing GPU trace '{}'..."), Path::GetFileName(source_path)), 60.0f);
System::QueueAsyncTask(
[compress_mode, source_path = std::move(source_path), osd_key = std::move(osd_key)]() mutable {
System::QueueAsyncTask([compress_mode, source_path = std::move(source_path), osd_key = std::move(osd_key)]() mutable {
Error error;
if (GPUDump::Recorder::Compress(source_path, compress_mode, &error))
{
@ -2166,6 +2165,15 @@ void GPU::WriteCurrentVideoModeToDump(GPUDump::Recorder* dump) const
void GPU::ProcessGPUDumpPacket(GPUDump::PacketType type, const std::span<const u32> data)
{
const auto execute_all_commands = [this]() {
do
{
m_pending_command_ticks = 0;
s_command_tick_event.Deactivate();
ExecuteCommands();
} while (m_pending_command_ticks > 0);
};
switch (type)
{
case GPUDump::PacketType::GPUPort0Data:
@ -2176,14 +2184,11 @@ void GPU::ProcessGPUDumpPacket(GPUDump::PacketType type, const std::span<const u
return;
}
// ensure it doesn't block
m_pending_command_ticks = 0;
UpdateCommandTickEvent();
if (data.size() == 1) [[unlikely]]
{
// direct GP0 write
WriteRegister(0, data[0]);
execute_all_commands();
}
else
{
@ -2191,7 +2196,9 @@ void GPU::ProcessGPUDumpPacket(GPUDump::PacketType type, const std::span<const u
size_t current_word = 0;
while (current_word < data.size())
{
const u32 block_size = std::min(m_fifo_size - m_fifo.GetSize(), static_cast<u32>(data.size() - current_word));
// normally this would be constrained to the "real" fifo size, but VRAM updates also go through here
// it's easier to just push everything in and execute
const u32 block_size = std::min(m_fifo.GetSpace(), static_cast<u32>(data.size() - current_word));
if (block_size == 0)
{
ERROR_LOG("FIFO overflow while processing dump packet of {} words", data.size());
@ -2200,7 +2207,9 @@ void GPU::ProcessGPUDumpPacket(GPUDump::PacketType type, const std::span<const u
for (u32 i = 0; i < block_size; i++)
m_fifo.Push(ZeroExtend64(data[current_word++]));
ExecuteCommands();
execute_all_commands();
;
}
}
}
@ -2221,8 +2230,7 @@ void GPU::ProcessGPUDumpPacket(GPUDump::PacketType type, const std::span<const u
case GPUDump::PacketType::VSyncEvent:
{
// don't play silly buggers with events
m_pending_command_ticks = 0;
UpdateCommandTickEvent();
execute_all_commands();
// we _should_ be using the tick count for the event, but it breaks with looping.
// instead, just add a fixed amount