aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/gpu_split.cpp
diff options
context:
space:
mode:
authornéo Luigi <85024393+neoluigi4123@users.noreply.github.com>2026-11-03 00:49:36 +0100
committernéo Luigi <85024393+neoluigi4123@users.noreply.github.com>2026-11-03 00:49:36 +0100
commitc84e5caf82a786f748c233e27b7f4ed9aaad9f44 (patch)
tree3ec9cab90d74292445d0a076370933bac946fc4d /src/video_core/gpu_split.cpp
parent2b413a46a2820f0a646baaa8dbd683009f096f32 (diff)
parentefa7c19e59839f0d464c2e9bd41f9ca8f867fef0 (diff)
Merge remote-tracking branch 'origin/nx2' into neo.ai/vibration-fix
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> # Conflicts: # src/core/hle/service/hid/hid_server.cpp # src/core/hle/service/hid/hid_server.h
Diffstat (limited to 'src/video_core/gpu_split.cpp')
-rw-r--r--src/video_core/gpu_split.cpp30
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;
}