mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-05-14 08:12:16 +00:00
Handle IT_WAIT_REG_MEM with Register argument (#2927)
This commit is contained in:
parent
1832ec2ac2
commit
e5b675d607
3 changed files with 22 additions and 12 deletions
|
@ -179,7 +179,7 @@ s32 PS4_SYSV_ABI sceGnmComputeWaitOnAddress(u32* cmdbuf, u32 size, uintptr_t add
|
|||
auto* wait_reg_mem = reinterpret_cast<PM4CmdWaitRegMem*>(cmdbuf);
|
||||
wait_reg_mem->header = PM4Type3Header{PM4ItOpcode::WaitRegMem, 5};
|
||||
wait_reg_mem->raw = (is_mem << 4u) | (cmp_func & 7u);
|
||||
wait_reg_mem->poll_addr_lo = u32(addr & addr_mask);
|
||||
wait_reg_mem->poll_addr_lo_raw = u32(addr & addr_mask);
|
||||
wait_reg_mem->poll_addr_hi = u32(addr >> 32u);
|
||||
wait_reg_mem->ref = ref;
|
||||
wait_reg_mem->mask = mask;
|
||||
|
|
|
@ -696,10 +696,10 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
|||
const u64* wait_addr = wait_reg_mem->Address<u64*>();
|
||||
if (vo_port->IsVoLabel(wait_addr) &&
|
||||
num_submits == mapped_queues[GfxQueueId].submits.size()) {
|
||||
vo_port->WaitVoLabel([&] { return wait_reg_mem->Test(); });
|
||||
vo_port->WaitVoLabel([&] { return wait_reg_mem->Test(regs.reg_array); });
|
||||
break;
|
||||
}
|
||||
while (!wait_reg_mem->Test()) {
|
||||
while (!wait_reg_mem->Test(regs.reg_array)) {
|
||||
YIELD_GFX();
|
||||
}
|
||||
break;
|
||||
|
@ -934,7 +934,7 @@ Liverpool::Task Liverpool::ProcessCompute(const u32* acb, u32 acb_dwords, u32 vq
|
|||
case PM4ItOpcode::WaitRegMem: {
|
||||
const auto* wait_reg_mem = reinterpret_cast<const PM4CmdWaitRegMem*>(header);
|
||||
ASSERT(wait_reg_mem->engine.Value() == PM4CmdWaitRegMem::Engine::Me);
|
||||
while (!wait_reg_mem->Test()) {
|
||||
while (!wait_reg_mem->Test(regs.reg_array)) {
|
||||
YIELD_ASC(vqid);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -474,7 +474,12 @@ struct PM4CmdWaitRegMem {
|
|||
BitField<8, 1, Engine> engine;
|
||||
u32 raw;
|
||||
};
|
||||
u32 poll_addr_lo;
|
||||
union {
|
||||
BitField<0, 16, u32> reg;
|
||||
BitField<2, 30, u32> poll_addr_lo;
|
||||
BitField<0, 2, u32> swap;
|
||||
u32 poll_addr_lo_raw;
|
||||
};
|
||||
u32 poll_addr_hi;
|
||||
u32 ref;
|
||||
u32 mask;
|
||||
|
@ -485,28 +490,33 @@ struct PM4CmdWaitRegMem {
|
|||
return std::bit_cast<T>((uintptr_t(poll_addr_hi) << 32) | poll_addr_lo);
|
||||
}
|
||||
|
||||
bool Test() const {
|
||||
u32 Reg() const {
|
||||
return reg.Value();
|
||||
}
|
||||
|
||||
bool Test(const std::array<u32, Liverpool::NumRegs>& regs) const {
|
||||
u32 value = mem_space.Value() == MemSpace::Memory ? *Address() : regs[Reg()];
|
||||
switch (function.Value()) {
|
||||
case Function::Always: {
|
||||
return true;
|
||||
}
|
||||
case Function::LessThan: {
|
||||
return (*Address() & mask) < ref;
|
||||
return (value & mask) < ref;
|
||||
}
|
||||
case Function::LessThanEqual: {
|
||||
return (*Address() & mask) <= ref;
|
||||
return (value & mask) <= ref;
|
||||
}
|
||||
case Function::Equal: {
|
||||
return (*Address() & mask) == ref;
|
||||
return (value & mask) == ref;
|
||||
}
|
||||
case Function::NotEqual: {
|
||||
return (*Address() & mask) != ref;
|
||||
return (value & mask) != ref;
|
||||
}
|
||||
case Function::GreaterThanEqual: {
|
||||
return (*Address() & mask) >= ref;
|
||||
return (value & mask) >= ref;
|
||||
}
|
||||
case Function::GreaterThan: {
|
||||
return (*Address() & mask) > ref;
|
||||
return (value & mask) > ref;
|
||||
}
|
||||
case Function::Reserved:
|
||||
[[fallthrough]];
|
||||
|
|
Loading…
Add table
Reference in a new issue