diff options
| author | Djihads <76681596+Djihads80@users.noreply.github.com> | 2026-10-30 16:00:28 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-10-30 16:00:28 +0100 |
| commit | 9e2d8d27a8f8065a74fd3d4eb51efc426bd742f7 (patch) | |
| tree | 23571ddb1fcf8f2b3cd1b856141cab3f3b756254 /src/video_core | |
| parent | 24e3cb462e47b22edda334939123694ff6920e95 (diff) | |
| parent | dfb3241838c17bd0e6c392cc29f24d085185dd73 (diff) | |
Merge pull request #38 from Djihads80/nx2-accuracy-switch
nx2: Fix the current crash when switching from fast to accurate and vice versa
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/dma_pusher.cpp | 5 | ||||
| -rw-r--r-- | src/video_core/gpu_split.cpp | 16 |
2 files changed, 16 insertions, 5 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()}; diff --git a/src/video_core/gpu_split.cpp b/src/video_core/gpu_split.cpp index 2bc8e29470..ac0d3f25f1 100644 --- a/src/video_core/gpu_split.cpp +++ b/src/video_core/gpu_split.cpp @@ -90,15 +90,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_; |
