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,27 +2103,26 @@ void GPU::StopRecordingGPUDump()
Host::AddIconOSDMessage( Host::AddIconOSDMessage(
osd_key, ICON_EMOJI_CAMERA_WITH_FLASH, osd_key, ICON_EMOJI_CAMERA_WITH_FLASH,
fmt::format(TRANSLATE_FS("GPU", "Compressing GPU trace '{}'..."), Path::GetFileName(source_path)), 60.0f); fmt::format(TRANSLATE_FS("GPU", "Compressing GPU trace '{}'..."), Path::GetFileName(source_path)), 60.0f);
System::QueueAsyncTask( System::QueueAsyncTask([compress_mode, source_path = std::move(source_path), osd_key = std::move(osd_key)]() mutable {
[compress_mode, source_path = std::move(source_path), osd_key = std::move(osd_key)]() mutable { Error error;
Error error; if (GPUDump::Recorder::Compress(source_path, compress_mode, &error))
if (GPUDump::Recorder::Compress(source_path, compress_mode, &error)) {
{ Host::AddIconOSDMessage(
Host::AddIconOSDMessage( std::move(osd_key), ICON_EMOJI_CAMERA_WITH_FLASH,
std::move(osd_key), ICON_EMOJI_CAMERA_WITH_FLASH, fmt::format(TRANSLATE_FS("GPU", "Saved GPU trace to '{}'."), Path::GetFileName(source_path)),
fmt::format(TRANSLATE_FS("GPU", "Saved GPU trace to '{}'."), Path::GetFileName(source_path)), Host::OSD_QUICK_DURATION);
Host::OSD_QUICK_DURATION); }
} else
else {
{ Host::AddIconOSDWarning(
Host::AddIconOSDWarning( std::move(osd_key), ICON_EMOJI_CAMERA_WITH_FLASH,
std::move(osd_key), ICON_EMOJI_CAMERA_WITH_FLASH, fmt::format("{}\n{}",
fmt::format("{}\n{}", SmallString::from_format(TRANSLATE_FS("GPU", "Failed to save GPU trace to '{}':"),
SmallString::from_format(TRANSLATE_FS("GPU", "Failed to save GPU trace to '{}':"), Path::GetFileName(source_path)),
Path::GetFileName(source_path)), error.GetDescription()),
error.GetDescription()), Host::OSD_ERROR_DURATION);
Host::OSD_ERROR_DURATION); }
} });
});
} }
void GPU::WriteCurrentVideoModeToDump(GPUDump::Recorder* dump) const void GPU::WriteCurrentVideoModeToDump(GPUDump::Recorder* dump) const
@ -2166,6 +2165,15 @@ void GPU::WriteCurrentVideoModeToDump(GPUDump::Recorder* dump) const
void GPU::ProcessGPUDumpPacket(GPUDump::PacketType type, const std::span<const u32> data) 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) switch (type)
{ {
case GPUDump::PacketType::GPUPort0Data: case GPUDump::PacketType::GPUPort0Data:
@ -2176,14 +2184,11 @@ void GPU::ProcessGPUDumpPacket(GPUDump::PacketType type, const std::span<const u
return; return;
} }
// ensure it doesn't block
m_pending_command_ticks = 0;
UpdateCommandTickEvent();
if (data.size() == 1) [[unlikely]] if (data.size() == 1) [[unlikely]]
{ {
// direct GP0 write // direct GP0 write
WriteRegister(0, data[0]); WriteRegister(0, data[0]);
execute_all_commands();
} }
else else
{ {
@ -2191,7 +2196,9 @@ void GPU::ProcessGPUDumpPacket(GPUDump::PacketType type, const std::span<const u
size_t current_word = 0; size_t current_word = 0;
while (current_word < data.size()) 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) if (block_size == 0)
{ {
ERROR_LOG("FIFO overflow while processing dump packet of {} words", data.size()); 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++) for (u32 i = 0; i < block_size; i++)
m_fifo.Push(ZeroExtend64(data[current_word++])); 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: case GPUDump::PacketType::VSyncEvent:
{ {
// don't play silly buggers with events // don't play silly buggers with events
m_pending_command_ticks = 0; execute_all_commands();
UpdateCommandTickEvent();
// we _should_ be using the tick count for the event, but it breaks with looping. // we _should_ be using the tick count for the event, but it breaks with looping.
// instead, just add a fixed amount // instead, just add a fixed amount