From bfb18135fb902eba27581f564519e8d1b058bb1e Mon Sep 17 00:00:00 2001 From: psucien Date: Wed, 8 May 2024 23:27:56 +0200 Subject: [PATCH] amdgpu: EOP irq and dummy PM4 handlers --- src/core/libraries/gnmdriver/gnmdriver.cpp | 2 +- src/video_core/amdgpu/liverpool.cpp | 75 ++++++++++++++++++---- src/video_core/amdgpu/pm4_cmds.h | 4 ++ src/video_core/amdgpu/pm4_opcodes.h | 2 +- 4 files changed, 69 insertions(+), 14 deletions(-) diff --git a/src/core/libraries/gnmdriver/gnmdriver.cpp b/src/core/libraries/gnmdriver/gnmdriver.cpp index 7e9a041b..dbe454b2 100644 --- a/src/core/libraries/gnmdriver/gnmdriver.cpp +++ b/src/core/libraries/gnmdriver/gnmdriver.cpp @@ -231,7 +231,7 @@ u32 PS4_SYSV_ABI sceGnmDispatchInitDefaultHardwareState(u32* cmdbuf, u32 size) { 0xffffffffu); // COMPUTE_STATIC_THREAD_MGMT_SE1 cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x215u, 0x170u); // COMPUTE_RESOURCE_LIMITS - cmdbuf = WriteHeader( + cmdbuf = WriteHeader( cmdbuf, 6); // for some reason the packet indicates larger size cmdbuf = WriteBody(cmdbuf, 0x28000000u, 0u, 0u, 0u, 0u); diff --git a/src/video_core/amdgpu/liverpool.cpp b/src/video_core/amdgpu/liverpool.cpp index 679cab90..c7db16ce 100644 --- a/src/video_core/amdgpu/liverpool.cpp +++ b/src/video_core/amdgpu/liverpool.cpp @@ -25,30 +25,30 @@ void Liverpool::ProcessCmdList(u32* cmdbuf, u32 size_in_bytes) { case PM4ItOpcode::Nop: break; case PM4ItOpcode::SetContextReg: { - auto* set_data = reinterpret_cast(header); + const auto* set_data = reinterpret_cast(header); std::memcpy(®s.reg_array[ContextRegWordOffset + set_data->reg_offset], header + 2, (count - 1) * sizeof(u32)); break; } case PM4ItOpcode::SetShReg: { - auto* set_data = reinterpret_cast(header); + const auto* set_data = reinterpret_cast(header); std::memcpy(®s.reg_array[ShRegWordOffset + set_data->reg_offset], header + 2, (count - 1) * sizeof(u32)); break; } case PM4ItOpcode::SetUconfigReg: { - auto* set_data = reinterpret_cast(header); + const auto* set_data = reinterpret_cast(header); std::memcpy(®s.reg_array[UconfigRegWordOffset + set_data->reg_offset], header + 2, (count - 1) * sizeof(u32)); break; } case PM4ItOpcode::IndexType: { - auto* index_type = reinterpret_cast(header); + const auto* index_type = reinterpret_cast(header); regs.index_buffer_type.raw = index_type->raw; break; } case PM4ItOpcode::DrawIndex2: { - auto* draw_index = reinterpret_cast(header); + const auto* draw_index = reinterpret_cast(header); regs.max_index_size = draw_index->max_size; regs.index_base_address.base_addr_lo = draw_index->index_base_lo; regs.index_base_address.base_addr_hi.Assign(draw_index->index_base_hi); @@ -58,22 +58,73 @@ void Liverpool::ProcessCmdList(u32* cmdbuf, u32 size_in_bytes) { break; } case PM4ItOpcode::DrawIndexAuto: { - auto* draw_index = reinterpret_cast(header); + const auto* draw_index = reinterpret_cast(header); regs.num_indices = draw_index->index_count; regs.draw_initiator = draw_index->draw_initiator; // rasterizer->DrawIndex(); break; } + case PM4ItOpcode::DispatchDirect: { + // const auto* dispatch_direct = reinterpret_cast(header); + break; + } + case PM4ItOpcode::EventWriteEos: { + // const auto* event_eos = reinterpret_cast(header); + break; + } case PM4ItOpcode::EventWriteEop: { - auto* event_write = reinterpret_cast(header); - const InterruptSelect irq_sel = event_write->int_sel; - const DataSelect data_sel = event_write->data_sel; - ASSERT(irq_sel == InterruptSelect::None && data_sel == DataSelect::Data64); - *event_write->Address() = event_write->DataQWord(); + const auto* event_eop = reinterpret_cast(header); + const InterruptSelect irq_sel = event_eop->int_sel; + const DataSelect data_sel = event_eop->data_sel; + + // Write back data if required + switch (data_sel) { + case DataSelect::Data32Low: { + *reinterpret_cast(event_eop->Address()) = event_eop->DataDWord(); + break; + } + case DataSelect::Data64: { + *event_eop->Address() = event_eop->DataQWord(); + break; + } + default: { + UNREACHABLE(); + } + } + + switch (irq_sel) { + case InterruptSelect::None: { + // No interrupt + break; + } + case InterruptSelect::IrqWhenWriteConfirm: { + if (eop_callback) { + eop_callback(); + } else { + UNREACHABLE_MSG("EOP callback is not registered"); + } + break; + } + default: { + UNREACHABLE(); + } + } break; } case PM4ItOpcode::DmaData: { - auto* dma_data = reinterpret_cast(header); + const auto* dma_data = reinterpret_cast(header); + break; + } + case PM4ItOpcode::WriteData: { + const auto* write_data = reinterpret_cast(header); + break; + } + case PM4ItOpcode::AcquireMem: { + // const auto* acquire_mem = reinterpret_cast(header); + break; + } + case PM4ItOpcode::WaitRegMem: { + const auto* wait_reg_mem = reinterpret_cast(header); break; } default: diff --git a/src/video_core/amdgpu/pm4_cmds.h b/src/video_core/amdgpu/pm4_cmds.h index bddd277a..6ce06750 100644 --- a/src/video_core/amdgpu/pm4_cmds.h +++ b/src/video_core/amdgpu/pm4_cmds.h @@ -286,6 +286,10 @@ struct PM4CmdEventWriteEop { return reinterpret_cast(address_lo | u64(address_hi) << 32); } + u32 DataDWord() const { + return data_lo; + } + u64 DataQWord() const { return data_lo | u64(data_hi) << 32; } diff --git a/src/video_core/amdgpu/pm4_opcodes.h b/src/video_core/amdgpu/pm4_opcodes.h index 2772716a..fb3fc8c5 100644 --- a/src/video_core/amdgpu/pm4_opcodes.h +++ b/src/video_core/amdgpu/pm4_opcodes.h @@ -49,7 +49,7 @@ enum class PM4ItOpcode : u32 { PremableCntl = 0x4A, DmaData = 0x50, ContextRegRmw = 0x51, - Unknown58 = 0x58, + AcquireMem = 0x58, LoadShReg = 0x5F, LoadConfigReg = 0x60, LoadContextReg = 0x61,