diff --git a/src/video_core/amdgpu/liverpool.cpp b/src/video_core/amdgpu/liverpool.cpp index 5fbb1acb..2e4566f5 100644 --- a/src/video_core/amdgpu/liverpool.cpp +++ b/src/video_core/amdgpu/liverpool.cpp @@ -69,7 +69,16 @@ void Liverpool::ProcessCmdList(u32* cmdbuf, u32 size_in_bytes) { break; } case PM4ItOpcode::EventWriteEos: { - // const auto* event_eos = reinterpret_cast(header); + const auto* event_eos = reinterpret_cast(header); + switch (event_eos->command.Value()) { + case PM4CmdEventWriteEos::Command::SingalFence: { + event_eos->SignalFence(); + break; + } + default: { + UNREACHABLE(); + } + } break; } case PM4ItOpcode::EventWriteEop: { diff --git a/src/video_core/amdgpu/pm4_cmds.h b/src/video_core/amdgpu/pm4_cmds.h index 762897fb..91e67a59 100644 --- a/src/video_core/amdgpu/pm4_cmds.h +++ b/src/video_core/amdgpu/pm4_cmds.h @@ -320,9 +320,9 @@ struct PM4DmaData { }; struct PM4CmdWaitRegMem { - enum Engine : u32 { Me = 0u, Pfp = 1u }; - enum MemSpace : u32 { Register = 0u, Memory = 1u }; - enum Function : u32 { + enum class Engine : u32 { Me = 0u, Pfp = 1u }; + enum class MemSpace : u32 { Register = 0u, Memory = 1u }; + enum class Function : u32 { Always = 0u, LessThan = 1u, LessThanEqual = 2u, @@ -335,9 +335,9 @@ struct PM4CmdWaitRegMem { PM4Type3Header header; union { - BitField<0, 3, u32> function; - BitField<4, 1, u32> mem_space; - BitField<8, 1, u32> engine; + BitField<0, 3, Function> function; + BitField<4, 1, MemSpace> mem_space; + BitField<8, 1, Engine> engine; u32 raw; }; u32 poll_addr_lo; @@ -400,4 +400,43 @@ struct PM4CmdWriteData { } }; +struct PM4CmdEventWriteEos { + enum class Command : u32 { + GdsStore = 1u, + SingalFence = 2u, + }; + + PM4Type3Header header; + union { + u32 event_control; + BitField<0, 6, u32> event_type; ///< Event type written to VGT_EVENT_INITIATOR + BitField<8, 4, u32> event_index; ///< Event index + }; + u32 address_lo; + union { + u32 cmd_info; + BitField<0, 16, u32> address_hi; ///< High bits of address + BitField<29, 3, Command> command; ///< Command + }; + union { + u32 data; ///< Fence value that will be written to memory when event occurs + BitField<0, 16, u32> + gds_index; ///< Indexed offset from the start of the segment within the partition + BitField<16, 16, u32> size; ///< Number of DWs to read from the GDS + }; + + u32* Address() const { + return reinterpret_cast(address_lo | u64(address_hi) << 32); + } + + u32 DataDWord() const { + return this->data; + } + + void SignalFence() const { + ASSERT_MSG(command.Value() == Command::SingalFence, "Invalid action on packet"); + *Address() = DataDWord(); + } +}; + } // namespace AmdGpu