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);
|
auto* wait_reg_mem = reinterpret_cast<PM4CmdWaitRegMem*>(cmdbuf);
|
||||||
wait_reg_mem->header = PM4Type3Header{PM4ItOpcode::WaitRegMem, 5};
|
wait_reg_mem->header = PM4Type3Header{PM4ItOpcode::WaitRegMem, 5};
|
||||||
wait_reg_mem->raw = (is_mem << 4u) | (cmp_func & 7u);
|
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->poll_addr_hi = u32(addr >> 32u);
|
||||||
wait_reg_mem->ref = ref;
|
wait_reg_mem->ref = ref;
|
||||||
wait_reg_mem->mask = mask;
|
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*>();
|
const u64* wait_addr = wait_reg_mem->Address<u64*>();
|
||||||
if (vo_port->IsVoLabel(wait_addr) &&
|
if (vo_port->IsVoLabel(wait_addr) &&
|
||||||
num_submits == mapped_queues[GfxQueueId].submits.size()) {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
while (!wait_reg_mem->Test()) {
|
while (!wait_reg_mem->Test(regs.reg_array)) {
|
||||||
YIELD_GFX();
|
YIELD_GFX();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -934,7 +934,7 @@ Liverpool::Task Liverpool::ProcessCompute(const u32* acb, u32 acb_dwords, u32 vq
|
||||||
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);
|
||||||
while (!wait_reg_mem->Test()) {
|
while (!wait_reg_mem->Test(regs.reg_array)) {
|
||||||
YIELD_ASC(vqid);
|
YIELD_ASC(vqid);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -474,7 +474,12 @@ struct PM4CmdWaitRegMem {
|
||||||
BitField<8, 1, Engine> engine;
|
BitField<8, 1, Engine> engine;
|
||||||
u32 raw;
|
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 poll_addr_hi;
|
||||||
u32 ref;
|
u32 ref;
|
||||||
u32 mask;
|
u32 mask;
|
||||||
|
@ -485,28 +490,33 @@ struct PM4CmdWaitRegMem {
|
||||||
return std::bit_cast<T>((uintptr_t(poll_addr_hi) << 32) | poll_addr_lo);
|
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()) {
|
switch (function.Value()) {
|
||||||
case Function::Always: {
|
case Function::Always: {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case Function::LessThan: {
|
case Function::LessThan: {
|
||||||
return (*Address() & mask) < ref;
|
return (value & mask) < ref;
|
||||||
}
|
}
|
||||||
case Function::LessThanEqual: {
|
case Function::LessThanEqual: {
|
||||||
return (*Address() & mask) <= ref;
|
return (value & mask) <= ref;
|
||||||
}
|
}
|
||||||
case Function::Equal: {
|
case Function::Equal: {
|
||||||
return (*Address() & mask) == ref;
|
return (value & mask) == ref;
|
||||||
}
|
}
|
||||||
case Function::NotEqual: {
|
case Function::NotEqual: {
|
||||||
return (*Address() & mask) != ref;
|
return (value & mask) != ref;
|
||||||
}
|
}
|
||||||
case Function::GreaterThanEqual: {
|
case Function::GreaterThanEqual: {
|
||||||
return (*Address() & mask) >= ref;
|
return (value & mask) >= ref;
|
||||||
}
|
}
|
||||||
case Function::GreaterThan: {
|
case Function::GreaterThan: {
|
||||||
return (*Address() & mask) > ref;
|
return (value & mask) > ref;
|
||||||
}
|
}
|
||||||
case Function::Reserved:
|
case Function::Reserved:
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
|
|
Loading…
Add table
Reference in a new issue