mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-01-29 01:38:24 +00:00
liverpool: Implement PM4 MEM_SEMAPHORE. (#2235)
Some checks are pending
Build and Release / reuse (push) Waiting to run
Build and Release / clang-format (push) Waiting to run
Build and Release / get-info (push) Waiting to run
Build and Release / windows-sdl (push) Blocked by required conditions
Build and Release / windows-qt (push) Blocked by required conditions
Build and Release / macos-sdl (push) Blocked by required conditions
Build and Release / macos-qt (push) Blocked by required conditions
Build and Release / linux-sdl (push) Blocked by required conditions
Build and Release / linux-qt (push) Blocked by required conditions
Build and Release / pre-release (push) Blocked by required conditions
Build and Release / linux-sdl-gcc (push) Blocked by required conditions
Build and Release / linux-qt-gcc (push) Blocked by required conditions
Some checks are pending
Build and Release / reuse (push) Waiting to run
Build and Release / clang-format (push) Waiting to run
Build and Release / get-info (push) Waiting to run
Build and Release / windows-sdl (push) Blocked by required conditions
Build and Release / windows-qt (push) Blocked by required conditions
Build and Release / macos-sdl (push) Blocked by required conditions
Build and Release / macos-qt (push) Blocked by required conditions
Build and Release / linux-sdl (push) Blocked by required conditions
Build and Release / linux-qt (push) Blocked by required conditions
Build and Release / pre-release (push) Blocked by required conditions
Build and Release / linux-sdl-gcc (push) Blocked by required conditions
Build and Release / linux-qt-gcc (push) Blocked by required conditions
This commit is contained in:
parent
564dbc7b94
commit
a5a1253185
|
@ -636,6 +636,18 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case PM4ItOpcode::MemSemaphore: {
|
||||||
|
const auto* mem_semaphore = reinterpret_cast<const PM4CmdMemSemaphore*>(header);
|
||||||
|
if (mem_semaphore->IsSignaling()) {
|
||||||
|
mem_semaphore->Signal();
|
||||||
|
} else {
|
||||||
|
while (!mem_semaphore->Signaled()) {
|
||||||
|
YIELD_GFX();
|
||||||
|
}
|
||||||
|
mem_semaphore->Decrement();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case PM4ItOpcode::AcquireMem: {
|
case PM4ItOpcode::AcquireMem: {
|
||||||
// const auto* acquire_mem = reinterpret_cast<PM4CmdAcquireMem*>(header);
|
// const auto* acquire_mem = reinterpret_cast<PM4CmdAcquireMem*>(header);
|
||||||
break;
|
break;
|
||||||
|
@ -848,6 +860,18 @@ Liverpool::Task Liverpool::ProcessCompute(std::span<const u32> acb, u32 vqid) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case PM4ItOpcode::MemSemaphore: {
|
||||||
|
const auto* mem_semaphore = reinterpret_cast<const PM4CmdMemSemaphore*>(header);
|
||||||
|
if (mem_semaphore->IsSignaling()) {
|
||||||
|
mem_semaphore->Signal();
|
||||||
|
} else {
|
||||||
|
while (!mem_semaphore->Signaled()) {
|
||||||
|
YIELD_ASC(vqid);
|
||||||
|
}
|
||||||
|
mem_semaphore->Decrement();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case PM4ItOpcode::WaitRegMem: {
|
case PM4ItOpcode::WaitRegMem: {
|
||||||
const auto* wait_reg_mem = reinterpret_cast<const PM4CmdWaitRegMem*>(header);
|
const auto* wait_reg_mem = reinterpret_cast<const PM4CmdWaitRegMem*>(header);
|
||||||
ASSERT(wait_reg_mem->engine.Value() == PM4CmdWaitRegMem::Engine::Me);
|
ASSERT(wait_reg_mem->engine.Value() == PM4CmdWaitRegMem::Engine::Me);
|
||||||
|
|
|
@ -884,4 +884,65 @@ struct PM4CmdDrawIndexIndirectMulti {
|
||||||
u32 draw_initiator; ///< Draw Initiator Register
|
u32 draw_initiator; ///< Draw Initiator Register
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PM4CmdMemSemaphore {
|
||||||
|
enum class ClientCode : u32 {
|
||||||
|
CommandProcessor = 0u,
|
||||||
|
CommandBuffer = 1u,
|
||||||
|
DataBuffer = 2u,
|
||||||
|
};
|
||||||
|
enum class Select : u32 {
|
||||||
|
SignalSemaphore = 6u,
|
||||||
|
WaitSemaphore = 7u,
|
||||||
|
};
|
||||||
|
enum class SignalType : u32 {
|
||||||
|
Increment = 0u,
|
||||||
|
Write = 1u,
|
||||||
|
};
|
||||||
|
|
||||||
|
PM4Type3Header header; ///< header
|
||||||
|
union {
|
||||||
|
u32 dw1;
|
||||||
|
BitField<3, 29, u32> addr_lo; ///< Semaphore address bits [31:3]
|
||||||
|
};
|
||||||
|
union {
|
||||||
|
u32 dw2;
|
||||||
|
BitField<0, 8, u32> addr_hi; ///< Semaphore address bits [39:32]
|
||||||
|
BitField<16, 1, u32> use_mailbox; ///< Enables waiting until mailbox is written to
|
||||||
|
BitField<20, 1, SignalType> signal_type; ///< Indicates the type of signal sent
|
||||||
|
BitField<24, 2, ClientCode> client_code;
|
||||||
|
BitField<29, 3, Select> sem_sel; ///< Indicates whether to do a signal or wait operation
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
[[nodiscard]] T Address() const {
|
||||||
|
return std::bit_cast<T>(u64(addr_lo) << 3 | (u64(addr_hi) << 32));
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool IsSignaling() const {
|
||||||
|
return sem_sel == Select::SignalSemaphore;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool Signaled() const {
|
||||||
|
return *Address<u64*>() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Decrement() const {
|
||||||
|
*Address<u64*>() -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Signal() const {
|
||||||
|
auto* ptr = Address<u64*>();
|
||||||
|
switch (signal_type) {
|
||||||
|
case SignalType::Increment:
|
||||||
|
*ptr += 1;
|
||||||
|
break;
|
||||||
|
case SignalType::Write:
|
||||||
|
*ptr = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
UNREACHABLE_MSG("Unknown signal type {}", static_cast<u32>(signal_type.Value()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace AmdGpu
|
} // namespace AmdGpu
|
||||||
|
|
Loading…
Reference in a new issue