Split NCE Trap page-out functionality from TrapRegions

The `TrapRegions` function performed a page-out on any regions that were trapped as read-only, this wasn't optimal as it would tie them both into the same operation while Buffers/Textures require to protect then synchronize and page-out. The trap was being moved to after the synchronize to get around this limitation but that can cause a potential race due to certain writes being done after the synchronization but prior to the trap which would be lost. This commit fixes these issues by splitting paging out into `PageOutRegions` which can be called after `TrapRegions` by any API users.

Co-authored-by: Billy Laws <blaws05@gmail.com>
This commit is contained in:
PixelyIon
2022-08-04 23:46:44 +01:00
parent da464d84bc
commit ffad246d67
4 changed files with 40 additions and 21 deletions

View File

@ -100,14 +100,17 @@ namespace skyline::gpu {
if (dirtyState == DirtyState::GpuDirty)
return;
else if (dirtyState == DirtyState::CpuDirty)
gpu.state.nce->TrapRegions(*trapHandle, false); // This has to occur prior to any synchronization as it'll skip trapping
if (dirtyState == DirtyState::CpuDirty)
SynchronizeHost(true); // Will transition the Buffer to Clean
dirtyState = DirtyState::GpuDirty;
gpu.state.nce->PageOutRegions(*trapHandle); // All data can be paged out from the guest as the guest mirror won't be used
BlockAllCpuBackingWrites();
AdvanceSequence(); // The GPU will modify buffer contents so advance to the next sequence
gpu.state.nce->TrapRegions(*trapHandle, false);
}
void Buffer::WaitOnFence() {