gnmdriver: submission lock moved out from gpu

This commit is contained in:
psucien 2024-05-17 23:31:19 +02:00
parent 058e728e29
commit 8455574615
2 changed files with 21 additions and 22 deletions

View File

@ -23,6 +23,9 @@ static std::unique_ptr<AmdGpu::Liverpool> liverpool;
// support is not important and can be ignored for a while. // support is not important and can be ignored for a while.
static constexpr bool g_fair_hw_init = false; 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 // Write a special ending NOP packet with N DWs data block
template <u32 data_block_size> template <u32 data_block_size>
static inline u32* WriteTrailingNop(u32* cmdbuf) { 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); eq->addEvent(kernel_event);
Platform::IrqC::Instance()->Register( Platform::IrqC::Instance()->Register(
Platform::InterruptId::GfxEop, [=](Platform::InterruptId irq) { Platform::InterruptId::GfxEop,
[=](Platform::InterruptId irq) {
ASSERT_MSG(irq == Platform::InterruptId::GfxEop, ASSERT_MSG(irq == Platform::InterruptId::GfxEop,
"An unexpected IRQ occured"); // We need to conver IRQ# to event id and do "An unexpected IRQ occured"); // We need to conver IRQ# to event id and do
// proper filtering in trigger function // proper filtering in trigger function
eq->triggerEvent(SceKernelEvent::Type::GfxEop, EVFILT_GRAPHICS_CORE, nullptr); eq->triggerEvent(SceKernelEvent::Type::GfxEop, EVFILT_GRAPHICS_CORE, nullptr);
}); },
eq);
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceGnmAreSubmitsAllowed() { int PS4_SYSV_ABI sceGnmAreSubmitsAllowed() {
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); LOG_TRACE(Lib_GnmDriver, "called");
return ORBIS_OK; return submission_lock == 0;
} }
int PS4_SYSV_ABI sceGnmBeginWorkload() { int PS4_SYSV_ABI sceGnmBeginWorkload() {
@ -165,7 +170,7 @@ s32 PS4_SYSV_ABI sceGnmDeleteEqEvent(SceKernelEqueue eq, u64 id) {
eq->removeEvent(id); eq->removeEvent(id);
Platform::IrqC::Instance()->Unregister(Platform::InterruptId::GfxEop); Platform::IrqC::Instance()->Unregister(Platform::InterruptId::GfxEop, eq);
return ORBIS_OK; 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) { for (auto cbpair = 0u; cbpair < count; ++cbpair) {
const auto* ccb = ccb_gpu_addrs ? ccb_gpu_addrs[cbpair] : nullptr; 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; 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() { int PS4_SYSV_ABI sceGnmSubmitDone() {
LOG_INFO(Lib_GnmDriver, "called"); LOG_INFO(Lib_GnmDriver, "called");
submission_lock = true;
liverpool->SubmitDone();
return ORBIS_OK; return ORBIS_OK;
} }

View File

@ -620,14 +620,6 @@ public:
~Liverpool(); ~Liverpool();
void SubmitGfx(std::span<const u32> dcb, std::span<const u32> ccb) { void SubmitGfx(std::span<const u32> dcb, std::span<const u32> ccb) {
if (submission_lock) {
WaitGpuIdle();
// Suspend logic goes here
submission_lock = false;
}
{ {
std::scoped_lock lock{m_ring_access}; std::scoped_lock lock{m_ring_access};
gfx_ring.emplace(dcb); gfx_ring.emplace(dcb);
@ -636,22 +628,18 @@ public:
} }
cv_submit.notify_one(); cv_submit.notify_one();
} }
void SubmitDone() {
submission_lock = true; void WaitGpuIdle();
}
private: private:
void ProcessCmdList(const u32* cmdbuf, u32 size_in_bytes); void ProcessCmdList(const u32* cmdbuf, u32 size_in_bytes);
void Process(std::stop_token stoken); void Process(std::stop_token stoken);
void WaitGpuIdle();
std::jthread process_thread{}; std::jthread process_thread{};
std::queue<std::span<const u32>> gfx_ring{}; std::queue<std::span<const u32>> gfx_ring{};
std::condition_variable_any cv_submit{}; std::condition_variable_any cv_submit{};
std::condition_variable cv_complete{}; std::condition_variable cv_complete{};
std::mutex m_ring_access{}; std::mutex m_ring_access{};
bool submission_lock{};
}; };
static_assert(GFX6_3D_REG_INDEX(ps_program) == 0x2C08); static_assert(GFX6_3D_REG_INDEX(ps_program) == 0x2C08);