From 84555746156296257ebbff6aab85a19d49668f75 Mon Sep 17 00:00:00 2001 From: psucien Date: Fri, 17 May 2024 23:31:19 +0200 Subject: [PATCH] gnmdriver: submission lock moved out from gpu --- src/core/libraries/gnmdriver/gnmdriver.cpp | 27 +++++++++++++++------- src/video_core/amdgpu/liverpool.h | 16 ++----------- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/core/libraries/gnmdriver/gnmdriver.cpp b/src/core/libraries/gnmdriver/gnmdriver.cpp index 5cb7f5a9..b79ef820 100644 --- a/src/core/libraries/gnmdriver/gnmdriver.cpp +++ b/src/core/libraries/gnmdriver/gnmdriver.cpp @@ -23,6 +23,9 @@ static std::unique_ptr liverpool; // support is not important and can be ignored for a while. static constexpr bool g_fair_hw_init = false; +// In case if `submitDone` is issued we need to block submissions until GPU idle +static u32 submission_lock{}; + // Write a special ending NOP packet with N DWs data block template static inline u32* WriteTrailingNop(u32* cmdbuf) { @@ -50,18 +53,20 @@ s32 PS4_SYSV_ABI sceGnmAddEqEvent(SceKernelEqueue eq, u64 id, void* udata) { eq->addEvent(kernel_event); Platform::IrqC::Instance()->Register( - Platform::InterruptId::GfxEop, [=](Platform::InterruptId irq) { + Platform::InterruptId::GfxEop, + [=](Platform::InterruptId irq) { ASSERT_MSG(irq == Platform::InterruptId::GfxEop, "An unexpected IRQ occured"); // We need to conver IRQ# to event id and do // proper filtering in trigger function eq->triggerEvent(SceKernelEvent::Type::GfxEop, EVFILT_GRAPHICS_CORE, nullptr); - }); + }, + eq); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmAreSubmitsAllowed() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); - return ORBIS_OK; + LOG_TRACE(Lib_GnmDriver, "called"); + return submission_lock == 0; } int PS4_SYSV_ABI sceGnmBeginWorkload() { @@ -165,7 +170,7 @@ s32 PS4_SYSV_ABI sceGnmDeleteEqEvent(SceKernelEqueue eq, u64 id) { eq->removeEvent(id); - Platform::IrqC::Instance()->Unregister(Platform::InterruptId::GfxEop); + Platform::IrqC::Instance()->Unregister(Platform::InterruptId::GfxEop, eq); return ORBIS_OK; } @@ -1411,6 +1416,14 @@ s32 PS4_SYSV_ABI sceGnmSubmitCommandBuffers(u32 count, const u32* dcb_gpu_addrs[ } } + if (submission_lock != 0) { + liverpool->WaitGpuIdle(); + + // Suspend logic goes here + + submission_lock = 0; + } + for (auto cbpair = 0u; cbpair < count; ++cbpair) { const auto* ccb = ccb_gpu_addrs ? ccb_gpu_addrs[cbpair] : nullptr; const auto ccb_size = ccb_sizes_in_bytes ? ccb_sizes_in_bytes[cbpair] : 0; @@ -1428,9 +1441,7 @@ int PS4_SYSV_ABI sceGnmSubmitCommandBuffersForWorkload() { int PS4_SYSV_ABI sceGnmSubmitDone() { LOG_INFO(Lib_GnmDriver, "called"); - - liverpool->SubmitDone(); - + submission_lock = true; return ORBIS_OK; } diff --git a/src/video_core/amdgpu/liverpool.h b/src/video_core/amdgpu/liverpool.h index c8e8eb0d..b40c9ba5 100644 --- a/src/video_core/amdgpu/liverpool.h +++ b/src/video_core/amdgpu/liverpool.h @@ -620,14 +620,6 @@ public: ~Liverpool(); void SubmitGfx(std::span dcb, std::span ccb) { - if (submission_lock) { - WaitGpuIdle(); - - // Suspend logic goes here - - submission_lock = false; - } - { std::scoped_lock lock{m_ring_access}; gfx_ring.emplace(dcb); @@ -636,22 +628,18 @@ public: } cv_submit.notify_one(); } - void SubmitDone() { - submission_lock = true; - } + + void WaitGpuIdle(); private: void ProcessCmdList(const u32* cmdbuf, u32 size_in_bytes); void Process(std::stop_token stoken); - void WaitGpuIdle(); std::jthread process_thread{}; std::queue> gfx_ring{}; std::condition_variable_any cv_submit{}; std::condition_variable cv_complete{}; std::mutex m_ring_access{}; - - bool submission_lock{}; }; static_assert(GFX6_3D_REG_INDEX(ps_program) == 0x2C08);