Split syncpoints into host-guest pairs

This allows for the presentation engine to grab the presentation image early when direct buffers are in use, since it'll handle sync on its own using semaphores it doesn't need to wait for GPU execution.
This commit is contained in:
Billy Laws 2022-12-27 19:12:13 +00:00
parent 966c31810a
commit 90e21b0ca1
7 changed files with 24 additions and 9 deletions

View File

@ -64,7 +64,7 @@ namespace skyline::service::hosbinder {
throw exception("Wait has larger fence count ({}) than storage size ({})", fenceCount, fences.size());
for (auto it{fences.begin()}, end{fences.begin() + fenceCount}; it < end; it++)
if (it->id != InvalidFenceId)
host1x.syncpoints.at(it->id).Wait(it->threshold, std::chrono::steady_clock::duration::max());
host1x.syncpoints.at(it->id).host.Wait(it->threshold, std::chrono::steady_clock::duration::max());
}
};

View File

@ -79,7 +79,7 @@ namespace skyline::service::nvdrv::core {
if (!syncpoints.at(id).reserved)
throw exception("Cannot update an unreserved syncpoint!");
syncpoints.at(id).counterMin = state.soc->host1x.syncpoints.at(id).Load();
syncpoints.at(id).counterMin = state.soc->host1x.syncpoints.at(id).host.Load();
return syncpoints.at(id).counterMin;
}

View File

@ -18,14 +18,14 @@ namespace skyline::service::nvdrv::device::nvhost {
}
void Ctrl::SyncpointEvent::Cancel(soc::host1x::Host1x &host1x) {
host1x.syncpoints.at(fence.id).DeregisterWaiter(waiterHandle);
host1x.syncpoints.at(fence.id).host.DeregisterWaiter(waiterHandle);
waiterHandle = {};
}
void Ctrl::SyncpointEvent::RegisterWaiter(soc::host1x::Host1x &host1x, const Fence &pFence) {
fence = pFence;
state = State::Waiting;
waiterHandle = host1x.syncpoints.at(fence.id).RegisterWaiter(fence.threshold, [this] { Signal(); });
waiterHandle = host1x.syncpoints.at(fence.id).host.RegisterWaiter(fence.threshold, [this] { Signal(); });
}
bool Ctrl::SyncpointEvent::IsInUse() {

View File

@ -20,8 +20,9 @@ namespace skyline::soc::gm20b::engine {
if (action.operation == Registers::Syncpoint::Operation::Incr) {
Logger::Debug("Increment syncpoint: {}", +action.index);
channelCtx.executor.Submit([=, syncpoints = &this->syncpoints, index = action.index]() {
syncpoints->at(index).Increment();
syncpoints->at(index).host.Increment();
});
syncpoints.at(action.index).guest.Increment();
} else if (action.operation == Registers::Syncpoint::Operation::Wait) {
Logger::Debug("Wait syncpoint: {}, thresh: {}", +action.index, registers.syncpoint->payload);
@ -29,7 +30,7 @@ namespace skyline::soc::gm20b::engine {
channelCtx.executor.Submit();
channelCtx.Unlock();
syncpoints.at(action.index).Wait(registers.syncpoint->payload, std::chrono::steady_clock::duration::max());
syncpoints.at(action.index).host.Wait(registers.syncpoint->payload, std::chrono::steady_clock::duration::max());
channelCtx.Lock();
}
})

View File

@ -219,8 +219,9 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
ENGINE_CASE(syncpointAction, {
Logger::Debug("Increment syncpoint: {}", static_cast<u16>(syncpointAction.id));
channelCtx.executor.Submit([=, syncpoints = &this->syncpoints, index = syncpointAction.id]() {
syncpoints->at(index).Increment();
syncpoints->at(index).host.Increment();
});
syncpoints.at(syncpointAction.id).guest.Increment();
})
ENGINE_CASE(clearSurface, {

View File

@ -30,7 +30,7 @@ namespace skyline::soc::host1x {
u32 syncpointId{static_cast<u8>(argument)};
Logger::Debug("Wait syncpoint: {}, thresh: {}", syncpointId, syncpointPayload);
syncpoints.at(syncpointId).Wait(syncpointPayload, std::chrono::steady_clock::duration::max());
syncpoints.at(syncpointId).host.Wait(syncpointPayload, std::chrono::steady_clock::duration::max());
break;
}

View File

@ -62,5 +62,18 @@ namespace skyline::soc::host1x {
bool Wait(u32 threshold, std::chrono::steady_clock::duration timeout);
};
using SyncpointSet = std::array<Syncpoint, SyncpointCount>;
/**
* @bried Holds host and guest copies of an individual syncpoint
*/
struct SyncpointPair {
Syncpoint guest; //!< Incremented at GPFIFO processing time
Syncpoint host; //!< Incremented after host GPU completion
void Increment() {
guest.Increment();
host.Increment();
}
};
using SyncpointSet = std::array<SyncpointPair, SyncpointCount>;
}