aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorWael3rd <29479851+Wael3rd@users.noreply.github.com>2026-10-31 07:34:16 +0100
committerkraibse <33869366+kraibse@users.noreply.github.com>2026-10-31 10:35:24 +0100
commitb7575b0305dcd5d312a12cdb1c04bf163034a395 (patch)
tree5e535dde5b7ffe0ab30fa2dcd4ecdb06802ffc3d /src
parentbb353609e6c2700014d7d1f1d50cf35e2c45a3b1 (diff)
nvdrv: clear the sparse region state with the other Switch 2 globals
Which blocks of each sparse region were written is global state, and a game stopped without destroying its regions left them there: the next game in the same window could find an image "unwritten" and create it with no memory. Clear the regions where nvdrv already resets the other Switch 2 globals. Assisted-by: Claude Opus 5.5 (diagnosis and code)
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.cpp1
-rw-r--r--src/video_core/nx2.h6
2 files changed, 7 insertions, 0 deletions
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp
index 2be24e3f57..12923496fb 100644
--- a/src/core/hle/service/nvdrv/nvdrv.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv.cpp
@@ -132,6 +132,7 @@ Module::Module(Core::System& system)
// (their table filled up, so the new game's GPU waits never completed) and the Switch 2 flags.
Devices::Nx2GpuMemoryRegistry::Get().Reset();
Tegra::Nx2ClearSemaphoreRegions();
+ Tegra::Nx2ClearSparseRegions();
Devices::g_nx2_driver = false;
Tegra::g_nx2_ampere = false;
Core::g_nx2_present_count = 0;
diff --git a/src/video_core/nx2.h b/src/video_core/nx2.h
index 4b0d3d5f62..824dc76044 100644
--- a/src/video_core/nx2.h
+++ b/src/video_core/nx2.h
@@ -116,6 +116,12 @@ inline void Nx2SparseRegionDestroyed(u64 gpu_address) {
g_nx2_sparse_state.erase(gpu_address);
}
+/// A new emulation session: the previous game's regions are gone (nvdrv's Module clears them).
+inline void Nx2ClearSparseRegions() {
+ std::scoped_lock lk{g_nx2_sparse_state_mutex};
+ g_nx2_sparse_state.clear();
+}
+
inline void Nx2SparseBlockWritten(u64 region_address, u64 block) {
std::scoped_lock lk{g_nx2_sparse_state_mutex};
if (const auto it = g_nx2_sparse_state.find(region_address); it != g_nx2_sparse_state.end()) {