aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/dma_pusher.cpp
diff options
context:
space:
mode:
authorkraibse <33869366+kraibse@users.noreply.github.com>2026-10-30 14:57:05 +0100
committerkraibse <33869366+kraibse@users.noreply.github.com>2026-10-30 14:57:05 +0100
commitdfb3241838c17bd0e6c392cc29f24d085185dd73 (patch)
tree8ca82f7977135c9e1889734e2573e8fecc08490d /src/video_core/dma_pusher.cpp
parent6e7edd7462325ee18a0db6fdc29ff7698ac108cc (diff)
nx2: apply GPU accuracy changes mid-game by stopping and restarting the GPU split
The split starts only with unsafe command reads, decided once at start-up. Switching to accurate afterwards made the front thread flush caches the back thread owns, which raced on Scheduler::chunk and crashed. MaybeStart now re-checks the settings between commands: it drains and stops the split when they no longer allow it and starts it again when they do. DmaPusher keeps unsafe reads while the split is active to cover the gap until then.
Diffstat (limited to 'src/video_core/dma_pusher.cpp')
-rw-r--r--src/video_core/dma_pusher.cpp5
1 files changed, 4 insertions, 1 deletions
diff --git a/src/video_core/dma_pusher.cpp b/src/video_core/dma_pusher.cpp
index 62f7e6bfdb..88d571ae5f 100644
--- a/src/video_core/dma_pusher.cpp
+++ b/src/video_core/dma_pusher.cpp
@@ -151,7 +151,10 @@ bool DmaPusher::Step() {
}
}
// A resumed entry is read again: the words after the acquire may be new by now.
- const bool use_safe = Settings::IsDMALevelDefault() ? Settings::IsGPULevelHigh() : Settings::IsDMALevelSafe();
+ // A safe read flushes the caches, which belong to the split's back thread while it runs
+ // (the split only starts with unsafe reads; the settings can change mid-game).
+ const bool use_safe = !VideoCommon::GpuSplit::Get().Active() &&
+ (Settings::IsDMALevelDefault() ? Settings::IsGPULevelHigh() : Settings::IsDMALevelSafe());
if (use_safe) {
Tegra::Memory::GpuGuestMemory<Tegra::CommandHeader, Tegra::Memory::GuestMemoryFlags::SafeRead>headers(memory_manager, dma_state.dma_get, header.size, &command_headers);
const std::span<const CommandHeader> commands{headers.data(), headers.size()};