diff options
| author | kraibse <33869366+kraibse@users.noreply.github.com> | 2026-10-30 14:57:05 +0100 |
|---|---|---|
| committer | kraibse <33869366+kraibse@users.noreply.github.com> | 2026-10-30 14:57:05 +0100 |
| commit | dfb3241838c17bd0e6c392cc29f24d085185dd73 (patch) | |
| tree | 8ca82f7977135c9e1889734e2573e8fecc08490d /src/video_core/gpu_split.cpp | |
| parent | 6e7edd7462325ee18a0db6fdc29ff7698ac108cc (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/gpu_split.cpp')
| -rw-r--r-- | src/video_core/gpu_split.cpp | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/src/video_core/gpu_split.cpp b/src/video_core/gpu_split.cpp index f913ca82ce..3997ea4565 100644 --- a/src/video_core/gpu_split.cpp +++ b/src/video_core/gpu_split.cpp @@ -88,15 +88,23 @@ void GpuSplit::MaybeStart(Core::System& system_) { return value != nullptr ? value[0] : '2'; }(); const bool wanted = mode == '1' || mode == '2'; - if (active || !wanted || !Tegra::g_nx2_ampere.load(std::memory_order_relaxed)) { + if (!wanted || !Tegra::g_nx2_ampere.load(std::memory_order_relaxed)) { return; } // The front reads command lists straight from guest memory; a read that flushes the caches - // first (safe DMA, accurate GPU) would touch back-owned state. + // first (safe DMA, accurate GPU) would touch back-owned state. The settings can change + // mid-game: hand the engines back to the front (and start again when they allow it). const bool safe_reads = Settings::IsDMALevelDefault() ? Settings::IsGPULevelHigh() : Settings::IsDMALevelSafe(); - if (safe_reads || Settings::IsGPULevelHigh() || - Settings::values.renderer_backend.GetValue() != Settings::RendererBackend::Vulkan) { + const bool allowed = !safe_reads && !Settings::IsGPULevelHigh() && + Settings::values.renderer_backend.GetValue() == Settings::RendererBackend::Vulkan; + if (active && !allowed) { + Drain(); + Stop(); + LOG_INFO(HW_GPU, "GPU thread split: stopped, the accuracy settings need the caches on the front"); + return; + } + if (active || !allowed) { return; } system = &system_; |
