diff options
| author | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-29 11:55:07 -0400 |
|---|---|---|
| committer | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-29 20:49:48 -0400 |
| commit | 15e953cafd5cb348833cb373d7ddd996b81307f7 (patch) | |
| tree | 3fd08c6943dd5b620fe1c899c283c1c78a6a5545 /src/video_core/gpu_split.cpp | |
| parent | 17c10c3690eab1ab461318f7e3e8850d490fb753 (diff) | |
video_core: GPU thread split on by default for Switch 2 titles; cheaper front paths
Clean A/B in title 1 (3 rounds each): 1.46x the draws a second of one
thread, frames 17% shorter, no crashes, front register copies equal to
the back's in 57,089 checks. EDEN_NX2_SPLIT=0 runs everything on one
thread, =1 keeps macros on the back.
The front's per-write paths no longer check guarded statics
(GpuSplit::Get, Nx2Profile::Enabled, the skip-same switches) and the
ring's method writes are inline. Notes row 145.
Diffstat (limited to 'src/video_core/gpu_split.cpp')
| -rw-r--r-- | src/video_core/gpu_split.cpp | 36 |
1 files changed, 4 insertions, 32 deletions
diff --git a/src/video_core/gpu_split.cpp b/src/video_core/gpu_split.cpp index 970fc0b559..07fda589ff 100644 --- a/src/video_core/gpu_split.cpp +++ b/src/video_core/gpu_split.cpp @@ -80,15 +80,12 @@ void GpuSplit::CheckOwner(const char* where) { #endif } -GpuSplit& GpuSplit::Get() { - static GpuSplit split; - return split; -} +GpuSplit GpuSplit::instance; void GpuSplit::MaybeStart(Core::System& system_) { static const char mode = [] { const char* value = std::getenv("EDEN_NX2_SPLIT"); - return value != nullptr ? value[0] : '0'; + 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)) { @@ -127,7 +124,7 @@ void GpuSplit::Stop() { active = false; } -u64* GpuSplit::Reserve(size_t words) { +u64* GpuSplit::ReserveSlow(size_t words) { size_t index = write_position & RingMask; if (index + words > RingWords) { // Entries never wrap: skip to the start of the ring. @@ -194,10 +191,7 @@ void GpuSplit::Drain() { } } -void GpuSplit::SelectEngine(Tegra::Engines::EngineInterface* engine) { - if (engine == front_engine) { - return; - } +void GpuSplit::SwitchEngine(Tegra::Engines::EngineInterface* engine) { front_engine = engine; u64* const entry = Reserve(2); entry[0] = static_cast<u64>(Kind::Engine); @@ -205,28 +199,6 @@ void GpuSplit::SelectEngine(Tegra::Engines::EngineInterface* engine) { Commit(2); } -void GpuSplit::Method(Tegra::Engines::EngineInterface* engine, u32 method, u32 argument, - bool is_last, const GPUVAddr* segment) { - SelectEngine(engine); - const size_t words = segment != nullptr ? 2 : 1; - u64* const entry = Reserve(words); - entry[0] = static_cast<u64>(Kind::Method) | (is_last ? IsLast : 0) | - (segment != nullptr ? HasSegment : 0) | (u64{method & 0xffff} << 8) | - (u64{argument} << 32); - if (segment != nullptr) { - entry[1] = *segment; - } - Commit(words); -} - -void GpuSplit::MacroWrite(Tegra::Engines::EngineInterface* engine, u32 method, u32 argument) { - SelectEngine(engine); - u64* const entry = Reserve(1); - entry[0] = static_cast<u64>(Kind::Method) | IsLast | Direct | (u64{method & 0xffff} << 8) | - (u64{argument} << 32); - Commit(1); -} - void GpuSplit::MultiMethod(Tegra::Engines::EngineInterface* engine, u32 method, const u32* words, u32 amount, u32 methods_pending, const GPUVAddr* segment) { SelectEngine(engine); |
