gnmdriver, amdgpu: added gpu idle IRQ; submission lock logic improved
This commit is contained in:
parent
bf74888be4
commit
986ed0662c
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/config.h"
|
#include "common/config.h"
|
||||||
|
#include "common/debug.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/path_util.h"
|
#include "common/path_util.h"
|
||||||
#include "common/slot_vector.h"
|
#include "common/slot_vector.h"
|
||||||
|
@ -264,6 +265,7 @@ static_assert(CtxInitSequence400.size() == 0x61);
|
||||||
|
|
||||||
// In case if `submitDone` is issued we need to block submissions until GPU idle
|
// In case if `submitDone` is issued we need to block submissions until GPU idle
|
||||||
static u32 submission_lock{};
|
static u32 submission_lock{};
|
||||||
|
std::condition_variable cv_lock{};
|
||||||
static std::mutex m_submission{};
|
static std::mutex m_submission{};
|
||||||
static u64 frames_submitted{}; // frame counter
|
static u64 frames_submitted{}; // frame counter
|
||||||
static bool send_init_packet{true}; // initialize HW state before first game's submit in a frame
|
static bool send_init_packet{true}; // initialize HW state before first game's submit in a frame
|
||||||
|
@ -277,6 +279,18 @@ struct AscQueueInfo {
|
||||||
static Common::SlotVector<AscQueueInfo> asc_queues{};
|
static Common::SlotVector<AscQueueInfo> asc_queues{};
|
||||||
static constexpr VAddr tessellation_factors_ring_addr = 0xFF0000000ULL;
|
static constexpr VAddr tessellation_factors_ring_addr = 0xFF0000000ULL;
|
||||||
|
|
||||||
|
static void ResetSubmissionLock(Platform::InterruptId irq) {
|
||||||
|
std::unique_lock lock{m_submission};
|
||||||
|
submission_lock = 0;
|
||||||
|
cv_lock.notify_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WaitGpuIdle() {
|
||||||
|
HLE_TRACE;
|
||||||
|
std::unique_lock lock{m_submission};
|
||||||
|
cv_lock.wait(lock, [] { return submission_lock == 0; });
|
||||||
|
}
|
||||||
|
|
||||||
static void DumpCommandList(std::span<const u32> cmd_list, const std::string& postfix) {
|
static void DumpCommandList(std::span<const u32> cmd_list, const std::string& postfix) {
|
||||||
using namespace Common::FS;
|
using namespace Common::FS;
|
||||||
const auto dump_dir = GetUserPath(PathType::PM4Dir);
|
const auto dump_dir = GetUserPath(PathType::PM4Dir);
|
||||||
|
@ -465,14 +479,9 @@ void PS4_SYSV_ABI sceGnmDingDong(u32 gnm_vqid, u32 next_offs_dw) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_lock lock{m_submission};
|
WaitGpuIdle();
|
||||||
if (submission_lock != 0) {
|
|
||||||
liverpool->WaitGpuIdle();
|
|
||||||
|
|
||||||
// Suspend logic goes here
|
/* Suspend logic goes here */
|
||||||
|
|
||||||
submission_lock = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto vqid = gnm_vqid - 1;
|
auto vqid = gnm_vqid - 1;
|
||||||
auto& asc_queue = asc_queues[{vqid}];
|
auto& asc_queue = asc_queues[{vqid}];
|
||||||
|
@ -1930,13 +1939,9 @@ s32 PS4_SYSV_ABI sceGnmSubmitCommandBuffers(u32 count, const u32* dcb_gpu_addrs[
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (submission_lock != 0) {
|
WaitGpuIdle();
|
||||||
liverpool->WaitGpuIdle();
|
|
||||||
|
|
||||||
// Suspend logic goes here
|
/* Suspend logic goes here */
|
||||||
|
|
||||||
submission_lock = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (send_init_packet) {
|
if (send_init_packet) {
|
||||||
if (sdk_version <= 0x1ffffffu) {
|
if (sdk_version <= 0x1ffffffu) {
|
||||||
|
@ -1990,7 +1995,6 @@ int PS4_SYSV_ABI sceGnmSubmitDone() {
|
||||||
if (!liverpool->IsGpuIdle()) {
|
if (!liverpool->IsGpuIdle()) {
|
||||||
submission_lock = true;
|
submission_lock = true;
|
||||||
}
|
}
|
||||||
liverpool->NotifySubmitDone();
|
|
||||||
send_init_packet = true;
|
send_init_packet = true;
|
||||||
++frames_submitted;
|
++frames_submitted;
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
|
@ -2471,6 +2475,9 @@ void RegisterlibSceGnmDriver(Core::Loader::SymbolsResolver* sym) {
|
||||||
sdk_version = 0;
|
sdk_version = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Platform::IrqC::Instance()->Register(Platform::InterruptId::GpuIdle, ResetSubmissionLock,
|
||||||
|
nullptr);
|
||||||
|
|
||||||
LIB_FUNCTION("b0xyllnVY-I", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmAddEqEvent);
|
LIB_FUNCTION("b0xyllnVY-I", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmAddEqEvent);
|
||||||
LIB_FUNCTION("b08AgtPlHPg", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1,
|
LIB_FUNCTION("b08AgtPlHPg", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1,
|
||||||
sceGnmAreSubmitsAllowed);
|
sceGnmAreSubmitsAllowed);
|
||||||
|
|
|
@ -26,6 +26,7 @@ enum class InterruptId : u32 {
|
||||||
Compute6RelMem = 6u,
|
Compute6RelMem = 6u,
|
||||||
GfxEop = 7u,
|
GfxEop = 7u,
|
||||||
GfxFlip = 8u,
|
GfxFlip = 8u,
|
||||||
|
GpuIdle = 9u,
|
||||||
};
|
};
|
||||||
|
|
||||||
using IrqHandler = std::function<void(InterruptId)>;
|
using IrqHandler = std::function<void(InterruptId)>;
|
||||||
|
|
|
@ -66,21 +66,10 @@ void Liverpool::Process(std::stop_token stoken) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (submit_done) {
|
Platform::IrqC::Instance()->Signal(Platform::InterruptId::GpuIdle);
|
||||||
std::scoped_lock lk{submit_mutex};
|
|
||||||
submit_cv.notify_all();
|
|
||||||
submit_done = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Liverpool::WaitGpuIdle() {
|
|
||||||
RENDERER_TRACE;
|
|
||||||
|
|
||||||
std::unique_lock lk{submit_mutex};
|
|
||||||
submit_cv.wait(lk, [this] { return num_submits == 0; });
|
|
||||||
}
|
|
||||||
|
|
||||||
Liverpool::Task Liverpool::ProcessCeUpdate(std::span<const u32> ccb) {
|
Liverpool::Task Liverpool::ProcessCeUpdate(std::span<const u32> ccb) {
|
||||||
TracyFiberEnter(ccb_task_name);
|
TracyFiberEnter(ccb_task_name);
|
||||||
|
|
||||||
|
|
|
@ -937,18 +937,10 @@ public:
|
||||||
void SubmitGfx(std::span<const u32> dcb, std::span<const u32> ccb);
|
void SubmitGfx(std::span<const u32> dcb, std::span<const u32> ccb);
|
||||||
void SubmitAsc(u32 vqid, std::span<const u32> acb);
|
void SubmitAsc(u32 vqid, std::span<const u32> acb);
|
||||||
|
|
||||||
void WaitGpuIdle();
|
|
||||||
|
|
||||||
bool IsGpuIdle() const {
|
bool IsGpuIdle() const {
|
||||||
return num_submits == 0;
|
return num_submits == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotifySubmitDone() {
|
|
||||||
std::scoped_lock lk{submit_mutex};
|
|
||||||
submit_done = true;
|
|
||||||
submit_cv.notify_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BindRasterizer(Vulkan::Rasterizer* rasterizer_) {
|
void BindRasterizer(Vulkan::Rasterizer* rasterizer_) {
|
||||||
rasterizer = rasterizer_;
|
rasterizer = rasterizer_;
|
||||||
}
|
}
|
||||||
|
@ -1017,7 +1009,6 @@ private:
|
||||||
u32 num_submits{};
|
u32 num_submits{};
|
||||||
std::mutex submit_mutex;
|
std::mutex submit_mutex;
|
||||||
std::condition_variable_any submit_cv;
|
std::condition_variable_any submit_cv;
|
||||||
std::atomic<bool> submit_done{};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(GFX6_3D_REG_INDEX(ps_program) == 0x2C08);
|
static_assert(GFX6_3D_REG_INDEX(ps_program) == 0x2C08);
|
||||||
|
|
Loading…
Reference in New Issue