Implement GPFIFO semaphore acquire operations

This commit is contained in:
Billy Laws 2022-10-30 16:37:37 +00:00
parent 2ce146e28f
commit 270ef3e0d2

View File

@ -41,10 +41,30 @@ namespace skyline::soc::gm20b::engine {
channelCtx.asCtx->gmmu.Write(address + 8, GetGpuTimeTicks()); channelCtx.asCtx->gmmu.Write(address + 8, GetGpuTimeTicks());
} }
if (action.operation == Registers::Semaphore::Operation::Release) { switch (action.operation) {
case Registers::Semaphore::Operation::Acquire:
Logger::Debug("Acquire semaphore: 0x{:X} payload: {}", address, registers.semaphore->payload);
channelCtx.Unlock();
while (channelCtx.asCtx->gmmu.Read<u32>(address) != registers.semaphore->payload)
std::this_thread::yield();
channelCtx.Lock();
break;
case Registers::Semaphore::Operation::Release:
channelCtx.asCtx->gmmu.Write(address, registers.semaphore->payload); channelCtx.asCtx->gmmu.Write(address, registers.semaphore->payload);
Logger::Debug("SemaphoreRelease: address: 0x{:X} payload: {}", address, registers.semaphore->payload); Logger::Debug("SemaphoreRelease: address: 0x{:X} payload: {}", address, registers.semaphore->payload);
} else if (action.operation == Registers::Semaphore::Operation::Reduction) { break;
case Registers::Semaphore::Operation::AcqGeq :
Logger::Debug("Acquire semaphore: 0x{:X} payload: {}", address, registers.semaphore->payload);
channelCtx.Unlock();
while (channelCtx.asCtx->gmmu.Read<u32>(address) < registers.semaphore->payload)
std::this_thread::yield();
channelCtx.Lock();
break;
case Registers::Semaphore::Operation::Reduction: {
u32 origVal{channelCtx.asCtx->gmmu.Read<u32>(address)}; u32 origVal{channelCtx.asCtx->gmmu.Read<u32>(address)};
bool isSigned{action.format == Registers::Semaphore::Format::Signed}; bool isSigned{action.format == Registers::Semaphore::Format::Signed};
@ -82,8 +102,11 @@ namespace skyline::soc::gm20b::engine {
address, static_cast<u8>(registers.semaphore->action.reduction), registers.semaphore->payload, origVal, val); address, static_cast<u8>(registers.semaphore->action.reduction), registers.semaphore->payload, origVal, val);
channelCtx.asCtx->gmmu.Write(address, val); channelCtx.asCtx->gmmu.Write(address, val);
} else { break;
}
default:
Logger::Warn("Unimplemented semaphore operation: 0x{:X}", static_cast<u8>(registers.semaphore->action.operation)); Logger::Warn("Unimplemented semaphore operation: 0x{:X}", static_cast<u8>(registers.semaphore->action.operation));
break;
} }
}) })
} }