diff options
| author | nowhere02 <140357165+nowhere02@users.noreply.github.com> | 2026-11-02 14:34:47 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-11-02 14:34:47 -0300 |
| commit | 62214094d6c698b70f51016e5c12af415f025be7 (patch) | |
| tree | 8cd09f385ce45afb7f00a95c839ea21d3ea81d41 /src/video_core/gpu_split.cpp | |
| parent | ead60c761e4d58cb4adc8b3b08f67dc10cf1e36b (diff) | |
| parent | 8f1435f8db104351fa3388551eee9d12d2043b40 (diff) | |
Merge pull request #322 from Djihads80/fix/nx2-cmdlist-copies
nx2: read GPU-written command lists from copies instead of draining
Diffstat (limited to 'src/video_core/gpu_split.cpp')
| -rw-r--r-- | src/video_core/gpu_split.cpp | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/src/video_core/gpu_split.cpp b/src/video_core/gpu_split.cpp index ac0d3f25f1..ef0cdae123 100644 --- a/src/video_core/gpu_split.cpp +++ b/src/video_core/gpu_split.cpp @@ -138,6 +138,7 @@ void GpuSplit::Stop() { // never ran, it waited on its syncpoint forever), and the engines it held were freed. ring.reset(); write_position = 0; + last_writer_position = 0; published_local = 0; consumed_cache = 0; publish_every = PublishEvery; @@ -216,6 +217,28 @@ void GpuSplit::Drain() { } } +void GpuSplit::WaitForWriters() { + const u64 target = std::min(last_writer_position, write_position); + consumed_cache = consumed.load(std::memory_order_acquire); + if (consumed_cache >= target) { + return; + } + wait_target.store(target, std::memory_order_seq_cst); + Publish(); + for (u32 spins = 0;; ++spins) { + consumed_cache = consumed.load(std::memory_order_acquire); + if (consumed_cache >= target) { + wait_target.store(~u64{0}, std::memory_order_relaxed); + return; + } + if (spins < 16384) { + Pause(); + } else { + std::this_thread::yield(); + } + } +} + void GpuSplit::SwitchEngine(Tegra::Engines::EngineInterface* engine) { front_engine = engine; u64* const entry = Reserve(2); @@ -346,8 +369,11 @@ void GpuSplit::BackLoop(std::stop_token stop_token) { const size_t index = read_position & RingMask; const size_t size = Execute(&ring[index]); read_position += size != 0 ? size : RingWords - index; - // Hand ring space back now and then while working through a long batch. - if (read_position - last_store >= 4096 && read_position != available) { + // Hand ring space back now and then while working through a long batch, and at once + // when the front waits for this position (WaitForWriters). + if ((read_position - last_store >= 4096 || + read_position >= wait_target.load(std::memory_order_relaxed)) && + read_position != available) { consumed.store(read_position, std::memory_order_release); last_store = read_position; } |
