mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-06-26 12:26:18 +00:00
core/gnmdriver: Proper interrupt registering (#1218)
This commit is contained in:
parent
72440a4996
commit
b7fe08519f
3 changed files with 38 additions and 32 deletions
|
@ -17,31 +17,35 @@
|
|||
namespace Platform {
|
||||
|
||||
enum class InterruptId : u32 {
|
||||
Compute0RelMem = 0u,
|
||||
Compute1RelMem = 1u,
|
||||
Compute2RelMem = 2u,
|
||||
Compute3RelMem = 3u,
|
||||
Compute4RelMem = 4u,
|
||||
Compute5RelMem = 5u,
|
||||
Compute6RelMem = 6u,
|
||||
GfxEop = 7u,
|
||||
GfxFlip = 8u,
|
||||
GpuIdle = 9u,
|
||||
Compute0RelMem = 0x00,
|
||||
Compute1RelMem = 0x01,
|
||||
Compute2RelMem = 0x02,
|
||||
Compute3RelMem = 0x03,
|
||||
Compute4RelMem = 0x04,
|
||||
Compute5RelMem = 0x05,
|
||||
Compute6RelMem = 0x06,
|
||||
GfxEop = 0x40,
|
||||
GfxFlip = 0x08,
|
||||
GpuIdle = 0x09,
|
||||
|
||||
InterruptIdMax = 0x40, ///< Max possible value (GfxEop)
|
||||
};
|
||||
|
||||
using IrqHandler = std::function<void(InterruptId)>;
|
||||
|
||||
struct IrqController {
|
||||
void RegisterOnce(InterruptId irq, IrqHandler handler) {
|
||||
ASSERT_MSG(static_cast<u32>(irq) < irq_contexts.size(), "Invalid IRQ number");
|
||||
auto& ctx = irq_contexts[static_cast<u32>(irq)];
|
||||
ASSERT_MSG(static_cast<u32>(irq) <= static_cast<u32>(InterruptId::InterruptIdMax),
|
||||
"Invalid IRQ number");
|
||||
auto& ctx = irq_contexts.try_emplace(irq).first->second;
|
||||
std::unique_lock lock{ctx.m_lock};
|
||||
ctx.one_time_subscribers.emplace(handler);
|
||||
}
|
||||
|
||||
void Register(InterruptId irq, IrqHandler handler, void* uid) {
|
||||
ASSERT_MSG(static_cast<u32>(irq) < irq_contexts.size(), "Invalid IRQ number");
|
||||
auto& ctx = irq_contexts[static_cast<u32>(irq)];
|
||||
ASSERT_MSG(static_cast<u32>(irq) <= static_cast<u32>(InterruptId::InterruptIdMax),
|
||||
"Invalid IRQ number");
|
||||
auto& ctx = irq_contexts.try_emplace(irq).first->second;
|
||||
|
||||
std::unique_lock lock{ctx.m_lock};
|
||||
ASSERT_MSG(ctx.persistent_handlers.find(uid) == ctx.persistent_handlers.cend(),
|
||||
|
@ -50,15 +54,17 @@ struct IrqController {
|
|||
}
|
||||
|
||||
void Unregister(InterruptId irq, void* uid) {
|
||||
ASSERT_MSG(static_cast<u32>(irq) < irq_contexts.size(), "Invalid IRQ number");
|
||||
auto& ctx = irq_contexts[static_cast<u32>(irq)];
|
||||
ASSERT_MSG(static_cast<u32>(irq) <= static_cast<u32>(InterruptId::InterruptIdMax),
|
||||
"Invalid IRQ number");
|
||||
auto& ctx = irq_contexts.try_emplace(irq).first->second;
|
||||
std::unique_lock lock{ctx.m_lock};
|
||||
ctx.persistent_handlers.erase(uid);
|
||||
}
|
||||
|
||||
void Signal(InterruptId irq) {
|
||||
ASSERT_MSG(static_cast<u32>(irq) < irq_contexts.size(), "Unexpected IRQ signaled");
|
||||
auto& ctx = irq_contexts[static_cast<u32>(irq)];
|
||||
ASSERT_MSG(static_cast<u32>(irq) <= static_cast<u32>(InterruptId::InterruptIdMax),
|
||||
"Unexpected IRQ signaled");
|
||||
auto& ctx = irq_contexts.try_emplace(irq).first->second;
|
||||
std::unique_lock lock{ctx.m_lock};
|
||||
|
||||
LOG_TRACE(Core, "IRQ signaled: {}", magic_enum::enum_name(irq));
|
||||
|
@ -81,7 +87,7 @@ private:
|
|||
std::queue<IrqHandler> one_time_subscribers{};
|
||||
std::mutex m_lock{};
|
||||
};
|
||||
std::array<IrqContext, magic_enum::enum_count<InterruptId>()> irq_contexts{};
|
||||
std::unordered_map<InterruptId, IrqContext> irq_contexts{};
|
||||
};
|
||||
|
||||
using IrqC = Common::Singleton<IrqController>;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue