GPU: Set idle bit during VRAM upload

Tenga Seiha does a bunch of completely-invalid VRAM writes on boot, then
expects GPU idle to be set. It's unclear what actually happens, I need to
write another test, but for now, just skip these uploads. Not setting GPU
idle during the write command breaks Doom, so that's not an option.
This commit is contained in:
Stenzek 2024-06-13 18:29:12 +10:00
parent edea81d151
commit ac1bb905fe
No known key found for this signature in database
2 changed files with 18 additions and 20 deletions

View file

@ -445,22 +445,7 @@ void GPU::UpdateDMARequest()
void GPU::UpdateGPUIdle() void GPU::UpdateGPUIdle()
{ {
switch (m_blitter_state) m_GPUSTAT.gpu_idle = (m_blitter_state == BlitterState::Idle && m_pending_command_ticks <= 0 && m_fifo.IsEmpty());
{
case BlitterState::Idle:
case BlitterState::DrawingPolyLine:
m_GPUSTAT.gpu_idle = (m_pending_command_ticks <= 0 && m_fifo.IsEmpty());
break;
case BlitterState::WritingVRAM:
case BlitterState::ReadingVRAM:
m_GPUSTAT.gpu_idle = m_fifo.IsEmpty();
break;
default:
UnreachableCode();
break;
}
} }
u32 GPU::ReadRegister(u32 offset) u32 GPU::ReadRegister(u32 offset)

View file

@ -479,10 +479,23 @@ bool GPU::HandleCopyRectangleCPUToVRAMCommand()
CHECK_COMMAND_SIZE(3); CHECK_COMMAND_SIZE(3);
m_fifo.RemoveOne(); m_fifo.RemoveOne();
const u32 dst_x = FifoPeek() & VRAM_WIDTH_MASK; const u32 coords = FifoPop();
const u32 dst_y = (FifoPop() >> 16) & VRAM_HEIGHT_MASK; const u32 size = FifoPop();
const u32 copy_width = ReplaceZero(FifoPeek() & VRAM_WIDTH_MASK, 0x400);
const u32 copy_height = ReplaceZero((FifoPop() >> 16) & VRAM_HEIGHT_MASK, 0x200); // Tenga Seiha does a bunch of completely-invalid VRAM writes on boot, then expects GPU idle to be set.
// It's unclear what actually happens, I need to write another test, but for now, just skip these uploads.
// Not setting GPU idle during the write command breaks Doom, so that's not an option.
if (size == 0xFFFFFFFFu) [[unlikely]]
{
ERROR_LOG("Ignoring likely-invalid VRAM write to ({},{})", (coords & VRAM_WIDTH_MASK),
((coords >> 16) & VRAM_HEIGHT_MASK));
return true;
}
const u32 dst_x = coords & VRAM_WIDTH_MASK;
const u32 dst_y = (coords >> 16) & VRAM_HEIGHT_MASK;
const u32 copy_width = ReplaceZero(size & VRAM_WIDTH_MASK, 0x400);
const u32 copy_height = ReplaceZero((size >> 16) & VRAM_HEIGHT_MASK, 0x200);
const u32 num_pixels = copy_width * copy_height; const u32 num_pixels = copy_width * copy_height;
const u32 num_words = ((num_pixels + 1) / 2); const u32 num_words = ((num_pixels + 1) / 2);