diff --git a/src/core/libraries/gnmdriver/gnmdriver.cpp b/src/core/libraries/gnmdriver/gnmdriver.cpp index 645bcf423..2d75741b4 100644 --- a/src/core/libraries/gnmdriver/gnmdriver.cpp +++ b/src/core/libraries/gnmdriver/gnmdriver.cpp @@ -304,6 +304,7 @@ struct AscQueueInfo { VAddr map_addr; u32* read_addr; u32 ring_size_dw; + u32 pipe_id; }; static Common::SlotVector asc_queues{}; static constexpr VAddr tessellation_factors_ring_addr = Core::SYSTEM_RESERVED_MAX - 0xFFFFFFF; @@ -371,15 +372,28 @@ s32 PS4_SYSV_ABI sceGnmAddEqEvent(SceKernelEqueue eq, u64 id, void* udata) { kernel_event.event.udata = udata; eq->AddEvent(kernel_event); + Platform::InterruptId interruptId; + GnmEventIdents eventId; + + if (id == 64) { + interruptId = Platform::InterruptId::GfxEop; + eventId = GnmEventIdents::GfxEop; + } else if (id >= 0 && id <= 6) { + interruptId = static_cast(id); + eventId = static_cast(id); + } else { + LOG_ERROR(Lib_GnmDriver, "unknown id {}", id); + return ORBIS_OK; + } + Platform::IrqC::Instance()->Register( - Platform::InterruptId::GfxEop, + interruptId, [=](Platform::InterruptId irq) { - ASSERT_MSG(irq == Platform::InterruptId::GfxEop, - "An unexpected IRQ occured"); // We need to convert IRQ# to event id and do - // proper filtering in trigger function - eq->TriggerEvent(GnmEventIdents::GfxEop, SceKernelEvent::Filter::GraphicsCore, nullptr); + ASSERT_MSG(irq == interruptId, "An unexpected IRQ occurred"); + eq->TriggerEvent(eventId, SceKernelEvent::Filter::GraphicsCore, nullptr); }, eq); + return ORBIS_OK; } @@ -540,15 +554,14 @@ void PS4_SYSV_ABI sceGnmDingDong(u32 gnm_vqid, u32 next_offs_dw) { DumpCommandList(acb, fmt::format("acb_{}_{}", gnm_vqid, seq_num)); } - liverpool->SubmitAsc(vqid, acb_span); + liverpool->SubmitAsc(vqid, acb_span, asc_queue.pipe_id); *asc_queue.read_addr += acb_size; *asc_queue.read_addr %= asc_queue.ring_size_dw * 4; } -int PS4_SYSV_ABI sceGnmDingDongForWorkload() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); - return ORBIS_OK; +void PS4_SYSV_ABI sceGnmDingDongForWorkload(u32 gnm_vqid, u32 next_offs_dw) { + sceGnmDingDong(gnm_vqid, next_offs_dw); } int PS4_SYSV_ABI sceGnmDisableMipStatsReport() { @@ -1192,7 +1205,7 @@ int PS4_SYSV_ABI sceGnmMapComputeQueue(u32 pipe_id, u32 queue_id, VAddr ring_bas return ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_READ_PTR_ADDR; } - auto vqid = asc_queues.insert(VAddr(ring_base_addr), read_ptr_addr, ring_size_dw); + auto vqid = asc_queues.insert(VAddr(ring_base_addr), read_ptr_addr, ring_size_dw, pipe_id); // We need to offset index as `dingDong` assumes it to be from the range [1..64] const auto gnm_vqid = vqid.index + 1; LOG_INFO(Lib_GnmDriver, "ASC pipe {} queue {} mapped to vqueue {}", pipe_id, queue_id, diff --git a/src/core/libraries/gnmdriver/gnmdriver.h b/src/core/libraries/gnmdriver/gnmdriver.h index 754d488f8..8bb0a582c 100644 --- a/src/core/libraries/gnmdriver/gnmdriver.h +++ b/src/core/libraries/gnmdriver/gnmdriver.h @@ -34,7 +34,7 @@ int PS4_SYSV_ABI sceGnmDebugHardwareStatus(); s32 PS4_SYSV_ABI sceGnmDeleteEqEvent(SceKernelEqueue eq, u64 id); int PS4_SYSV_ABI sceGnmDestroyWorkloadStream(); void PS4_SYSV_ABI sceGnmDingDong(u32 gnm_vqid, u32 next_offs_dw); -int PS4_SYSV_ABI sceGnmDingDongForWorkload(); +void PS4_SYSV_ABI sceGnmDingDongForWorkload(u32 gnm_vqid, u32 next_offs_dw); int PS4_SYSV_ABI sceGnmDisableMipStatsReport(); s32 PS4_SYSV_ABI sceGnmDispatchDirect(u32* cmdbuf, u32 size, u32 threads_x, u32 threads_y, u32 threads_z, u32 flags); diff --git a/src/video_core/amdgpu/liverpool.cpp b/src/video_core/amdgpu/liverpool.cpp index a2bd60f2e..a1588154a 100644 --- a/src/video_core/amdgpu/liverpool.cpp +++ b/src/video_core/amdgpu/liverpool.cpp @@ -562,7 +562,7 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span dcb, std::span acb, int vqid) { +Liverpool::Task Liverpool::ProcessCompute(std::span acb, int vqid, u32 pipeId) { TracyFiberEnter(acb_task_name); while (!acb.empty()) { @@ -584,7 +584,7 @@ Liverpool::Task Liverpool::ProcessCompute(std::span acb, int vqid) { case PM4ItOpcode::IndirectBuffer: { const auto* indirect_buffer = reinterpret_cast(header); auto task = ProcessCompute( - {indirect_buffer->Address(), indirect_buffer->ib_size}, vqid); + {indirect_buffer->Address(), indirect_buffer->ib_size}, vqid, pipeId); while (!task.handle.done()) { task.handle.resume(); @@ -642,7 +642,7 @@ Liverpool::Task Liverpool::ProcessCompute(std::span acb, int vqid) { } case PM4ItOpcode::ReleaseMem: { const auto* release_mem = reinterpret_cast(header); - release_mem->SignalFence(Platform::InterruptId::Compute0RelMem); // <--- + release_mem->SignalFence((Platform::InterruptId)pipeId); break; } default: @@ -704,11 +704,11 @@ void Liverpool::SubmitGfx(std::span dcb, std::span ccb) { submit_cv.notify_one(); } -void Liverpool::SubmitAsc(u32 vqid, std::span acb) { +void Liverpool::SubmitAsc(u32 vqid, std::span acb, u32 pipeId) { ASSERT_MSG(vqid >= 0 && vqid < NumTotalQueues, "Invalid virtual ASC queue index"); auto& queue = mapped_queues[vqid]; - const auto& task = ProcessCompute(acb, vqid); + const auto& task = ProcessCompute(acb, vqid, pipeId); { std::scoped_lock lock{queue.m_access}; queue.submits.emplace(task.handle); diff --git a/src/video_core/amdgpu/liverpool.h b/src/video_core/amdgpu/liverpool.h index 37720168a..8bb141303 100644 --- a/src/video_core/amdgpu/liverpool.h +++ b/src/video_core/amdgpu/liverpool.h @@ -1054,7 +1054,7 @@ public: ~Liverpool(); void SubmitGfx(std::span dcb, std::span ccb); - void SubmitAsc(u32 vqid, std::span acb); + void SubmitAsc(u32 vqid, std::span acb, u32 pipeId); void SubmitDone() noexcept { std::scoped_lock lk{submit_mutex}; @@ -1125,7 +1125,7 @@ private: std::span ccb); Task ProcessGraphics(std::span dcb, std::span ccb); Task ProcessCeUpdate(std::span ccb); - Task ProcessCompute(std::span acb, int vqid); + Task ProcessCompute(std::span acb, int vqid, u32 pipeId); void Process(std::stop_token stoken);