gnmdriver: submission lock moved out from gpu
This commit is contained in:
parent
058e728e29
commit
8455574615
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue