From 3e8bd269787acee8fd2d587ca72782fcd2c11724 Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Sun, 9 Oct 2022 12:51:27 +0100 Subject: [PATCH] Add a global gm20b channel lock Allowing for parallel execution of channels never really benefitted many games and prevented optimisations such as keeping frequently used resources always locked to avoid the constant overhead of locking on the hot path. --- app/src/main/cpp/skyline/gpu.h | 2 ++ app/src/main/cpp/skyline/soc/gm20b/channel.cpp | 3 ++- app/src/main/cpp/skyline/soc/gm20b/channel.h | 11 +++++++++++ .../main/cpp/skyline/soc/gm20b/engines/gpfifo.cpp | 3 +++ app/src/main/cpp/skyline/soc/gm20b/gpfifo.cpp | 14 ++++++++++++-- 5 files changed, 30 insertions(+), 3 deletions(-) diff --git a/app/src/main/cpp/skyline/gpu.h b/app/src/main/cpp/skyline/gpu.h index 33959cd4..7e7b11bc 100644 --- a/app/src/main/cpp/skyline/gpu.h +++ b/app/src/main/cpp/skyline/gpu.h @@ -57,6 +57,8 @@ namespace skyline::gpu { cache::RenderPassCache renderPassCache; cache::FramebufferCache framebufferCache; + std::mutex channelLock; + GPU(const DeviceState &state); }; } diff --git a/app/src/main/cpp/skyline/soc/gm20b/channel.cpp b/app/src/main/cpp/skyline/soc/gm20b/channel.cpp index aacc5c43..c6372acc 100644 --- a/app/src/main/cpp/skyline/soc/gm20b/channel.cpp +++ b/app/src/main/cpp/skyline/soc/gm20b/channel.cpp @@ -12,5 +12,6 @@ namespace skyline::soc::gm20b { maxwellDma(state, *this, executor), keplerCompute(state, *this), inline2Memory(*this), - gpfifo(state, *this, numEntries) {} + gpfifo(state, *this, numEntries), + globalChannelLock{state.gpu->channelLock} {} } diff --git a/app/src/main/cpp/skyline/soc/gm20b/channel.h b/app/src/main/cpp/skyline/soc/gm20b/channel.h index 30f72525..b79a60b1 100644 --- a/app/src/main/cpp/skyline/soc/gm20b/channel.h +++ b/app/src/main/cpp/skyline/soc/gm20b/channel.h @@ -30,7 +30,18 @@ namespace skyline::soc::gm20b { engine::KeplerCompute keplerCompute; engine::Inline2Memory inline2Memory; ChannelGpfifo gpfifo; + std::mutex &globalChannelLock; ChannelContext(const DeviceState &state, std::shared_ptr asCtx, size_t numEntries); + + void Lock() { + globalChannelLock.lock(); + executor.LockPreserve(); + } + + void Unlock() { + executor.UnlockPreserve(); + globalChannelLock.unlock(); + } }; } diff --git a/app/src/main/cpp/skyline/soc/gm20b/engines/gpfifo.cpp b/app/src/main/cpp/skyline/soc/gm20b/engines/gpfifo.cpp index 7b1db598..f447a990 100644 --- a/app/src/main/cpp/skyline/soc/gm20b/engines/gpfifo.cpp +++ b/app/src/main/cpp/skyline/soc/gm20b/engines/gpfifo.cpp @@ -25,7 +25,10 @@ namespace skyline::soc::gm20b::engine { Logger::Debug("Wait syncpoint: {}, thresh: {}", +action.index, registers.syncpoint->payload); // Wait forever for another channel to increment + + channelCtx.Unlock(); syncpoints.at(action.index).Wait(registers.syncpoint->payload, std::chrono::steady_clock::duration::max()); + channelCtx.Lock(); } }) diff --git a/app/src/main/cpp/skyline/soc/gm20b/gpfifo.cpp b/app/src/main/cpp/skyline/soc/gm20b/gpfifo.cpp index b7dac13d..5be67c7a 100644 --- a/app/src/main/cpp/skyline/soc/gm20b/gpfifo.cpp +++ b/app/src/main/cpp/skyline/soc/gm20b/gpfifo.cpp @@ -340,13 +340,23 @@ namespace skyline::soc::gm20b { signal::SetSignalHandler({SIGINT, SIGILL, SIGTRAP, SIGBUS, SIGFPE}, signal::ExceptionalSignalHandler); signal::SetSignalHandler({SIGSEGV}, nce::NCE::HostSignalHandler); // We may access NCE trapped memory - gpEntries.Process([this](GpEntry gpEntry) { + bool channelLocked{}; + + gpEntries.Process([this, &channelLocked](GpEntry gpEntry) { Logger::Debug("Processing pushbuffer: 0x{:X}, Size: 0x{:X}", gpEntry.Address(), +gpEntry.size); + + if (!channelLocked) { + channelCtx.Lock(); + channelLocked = true; + } + Process(gpEntry); - }, [this]() { + }, [this, &channelLocked]() { // If we run out of GpEntries to process ensure we submit any remaining GPU work before waiting for more to arrive Logger::Debug("Finished processing pushbuffer batch"); channelCtx.executor.Submit(); + channelCtx.Unlock(); + channelLocked = false; }); } catch (const signal::SignalException &e) { if (e.signal != SIGINT) {