mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-05 00:42:48 +00:00
Implement MEM_SEMAPHORE as a global pipeline barrier
This commit is contained in:
parent
83509271ca
commit
2c1aa0fb56
@ -289,6 +289,25 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
|||||||
case PM4ItOpcode::ContextControl: {
|
case PM4ItOpcode::ContextControl: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case PM4ItOpcode::MemSemaphore: {
|
||||||
|
const auto* mem_semaphore = reinterpret_cast<const PM4CmdMemSemaphore*>(header);
|
||||||
|
const auto addr = mem_semaphore->Address<VAddr>();
|
||||||
|
const auto select = mem_semaphore->semSel;
|
||||||
|
const auto client = mem_semaphore->clientCode;
|
||||||
|
const auto signal_type = mem_semaphore->signalType;
|
||||||
|
LOG_WARNING(Lib_GnmDriver, "MemSemaphore ignored: addr {:#X}, select {}, client {}, signal {}, wait {}, mailbox {}",
|
||||||
|
addr,
|
||||||
|
select.Value() == PM4CmdMemSemaphore::MemSemaphoreSelect::SignalSemaphore ? "signal" : "wait",
|
||||||
|
client.Value() == PM4CmdMemSemaphore::MemSemaphoreClientCode::CP ? "CP" : std::to_string(std::to_underlying(client.Value())),
|
||||||
|
std::to_underlying(signal_type.Value()) == 1 ? "increment/decrement" : "set 1/do nothing",
|
||||||
|
mem_semaphore->waitOnSignal.Value(),
|
||||||
|
std::to_underlying(mem_semaphore->useMailbox.Value())
|
||||||
|
);
|
||||||
|
if (rasterizer) {
|
||||||
|
rasterizer->GlobalBarrier();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case PM4ItOpcode::ClearState: {
|
case PM4ItOpcode::ClearState: {
|
||||||
regs.SetDefaults();
|
regs.SetDefaults();
|
||||||
break;
|
break;
|
||||||
@ -845,6 +864,25 @@ Liverpool::Task Liverpool::ProcessCompute(std::span<const u32> acb, u32 vqid) {
|
|||||||
release_mem->SignalFence(static_cast<Platform::InterruptId>(queue.pipe_id));
|
release_mem->SignalFence(static_cast<Platform::InterruptId>(queue.pipe_id));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case PM4ItOpcode::MemSemaphore: {
|
||||||
|
const auto* mem_semaphore = reinterpret_cast<const PM4CmdMemSemaphore*>(header);
|
||||||
|
const auto addr = mem_semaphore->Address<VAddr>();
|
||||||
|
const auto select = mem_semaphore->semSel;
|
||||||
|
const auto client = mem_semaphore->clientCode;
|
||||||
|
const auto signal_type = mem_semaphore->signalType;
|
||||||
|
LOG_WARNING(Lib_GnmDriver, "MemSemaphore ignored: addr {:#X}, select {}, client {}, signal {}, wait {}, mailbox {}",
|
||||||
|
addr,
|
||||||
|
select.Value() == PM4CmdMemSemaphore::MemSemaphoreSelect::SignalSemaphore ? "signal" : "wait",
|
||||||
|
client.Value() == PM4CmdMemSemaphore::MemSemaphoreClientCode::CP ? "CP" : std::to_string(std::to_underlying(client.Value())),
|
||||||
|
std::to_underlying(signal_type.Value()) == 1 ? "increment/decrement" : "set 1/do nothing",
|
||||||
|
mem_semaphore->waitOnSignal.Value(),
|
||||||
|
std::to_underlying(mem_semaphore->useMailbox.Value())
|
||||||
|
);
|
||||||
|
if (rasterizer) {
|
||||||
|
rasterizer->GlobalBarrier();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
UNREACHABLE_MSG("Unknown PM4 type 3 opcode {:#x} with count {}",
|
UNREACHABLE_MSG("Unknown PM4 type 3 opcode {:#x} with count {}",
|
||||||
static_cast<u32>(opcode), count);
|
static_cast<u32>(opcode), count);
|
||||||
|
@ -876,15 +876,15 @@ struct PM4CmdMemSemaphore {
|
|||||||
};
|
};
|
||||||
enum class MemSemaphoreSelect : u32 {
|
enum class MemSemaphoreSelect : u32 {
|
||||||
SignalSemaphore = 0b110u,
|
SignalSemaphore = 0b110u,
|
||||||
WaitSemaphore = 0b1111u
|
WaitSemaphore = 0b111u
|
||||||
};
|
};
|
||||||
enum class MemSemaphoreUseMailbox : u32 {
|
enum class MemSemaphoreUseMailbox : u32 {
|
||||||
DoNotWaitForMailboxToBeWritten = 0u,
|
DoNotWaitForMailboxToBeWritten = 0u,
|
||||||
WaitForMailboxToBeWritten = 1u
|
WaitForMailboxToBeWritten = 1u
|
||||||
};
|
};
|
||||||
enum class MemSemaphoreSignalType : u32 {
|
enum class MemSemaphoreSignalType : u32 {
|
||||||
SignalIncrementOrWait = 0u,
|
SignalIncrementOrDecrement = 0u,
|
||||||
SignalSetOne = 1u
|
SignalSetOneOrDoNothing = 1u
|
||||||
};
|
};
|
||||||
|
|
||||||
PM4Type3Header header; ///< header
|
PM4Type3Header header; ///< header
|
||||||
@ -906,7 +906,7 @@ struct PM4CmdMemSemaphore {
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T Address() const {
|
T Address() const {
|
||||||
return reinterpret_cast<T>(addr_lo | u64(addr_hi) << 32);
|
return reinterpret_cast<T>(u64(addr_lo) << 3 | (u64(addr_hi) << 32));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -47,6 +47,19 @@ void Rasterizer::CpSync() {
|
|||||||
vk::DependencyFlagBits::eByRegion, ib_barrier, {}, {});
|
vk::DependencyFlagBits::eByRegion, ib_barrier, {}, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Rasterizer::GlobalBarrier() {
|
||||||
|
scheduler.EndRendering();
|
||||||
|
auto cmdbuf = scheduler.CommandBuffer();
|
||||||
|
|
||||||
|
const vk::MemoryBarrier mem_barrier{
|
||||||
|
.srcAccessMask = vk::AccessFlagBits::eMemoryWrite,
|
||||||
|
.dstAccessMask = vk::AccessFlagBits::eMemoryRead,
|
||||||
|
};
|
||||||
|
cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eAllCommands,
|
||||||
|
vk::PipelineStageFlagBits::eAllCommands,
|
||||||
|
vk::DependencyFlagBits::eByRegion, {mem_barrier}, {}, {});
|
||||||
|
}
|
||||||
|
|
||||||
bool Rasterizer::FilterDraw() {
|
bool Rasterizer::FilterDraw() {
|
||||||
const auto& regs = liverpool->regs;
|
const auto& regs = liverpool->regs;
|
||||||
// There are several cases (e.g. FCE, FMask/HTile decompression) where we don't need to do an
|
// There are several cases (e.g. FCE, FMask/HTile decompression) where we don't need to do an
|
||||||
|
@ -60,6 +60,7 @@ public:
|
|||||||
void UnmapMemory(VAddr addr, u64 size);
|
void UnmapMemory(VAddr addr, u64 size);
|
||||||
|
|
||||||
void CpSync();
|
void CpSync();
|
||||||
|
void GlobalBarrier();
|
||||||
u64 Flush();
|
u64 Flush();
|
||||||
void Finish();
|
void Finish();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user