mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-23 19:51:52 +01:00
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:
parent
966c31810a
commit
90e21b0ca1
@ -64,7 +64,7 @@ namespace skyline::service::hosbinder {
|
|||||||
throw exception("Wait has larger fence count ({}) than storage size ({})", fenceCount, fences.size());
|
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++)
|
for (auto it{fences.begin()}, end{fences.begin() + fenceCount}; it < end; it++)
|
||||||
if (it->id != InvalidFenceId)
|
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());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ namespace skyline::service::nvdrv::core {
|
|||||||
if (!syncpoints.at(id).reserved)
|
if (!syncpoints.at(id).reserved)
|
||||||
throw exception("Cannot update an unreserved syncpoint!");
|
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;
|
return syncpoints.at(id).counterMin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,14 +18,14 @@ namespace skyline::service::nvdrv::device::nvhost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Ctrl::SyncpointEvent::Cancel(soc::host1x::Host1x &host1x) {
|
void Ctrl::SyncpointEvent::Cancel(soc::host1x::Host1x &host1x) {
|
||||||
host1x.syncpoints.at(fence.id).DeregisterWaiter(waiterHandle);
|
host1x.syncpoints.at(fence.id).host.DeregisterWaiter(waiterHandle);
|
||||||
waiterHandle = {};
|
waiterHandle = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ctrl::SyncpointEvent::RegisterWaiter(soc::host1x::Host1x &host1x, const Fence &pFence) {
|
void Ctrl::SyncpointEvent::RegisterWaiter(soc::host1x::Host1x &host1x, const Fence &pFence) {
|
||||||
fence = pFence;
|
fence = pFence;
|
||||||
state = State::Waiting;
|
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() {
|
bool Ctrl::SyncpointEvent::IsInUse() {
|
||||||
|
@ -20,8 +20,9 @@ namespace skyline::soc::gm20b::engine {
|
|||||||
if (action.operation == Registers::Syncpoint::Operation::Incr) {
|
if (action.operation == Registers::Syncpoint::Operation::Incr) {
|
||||||
Logger::Debug("Increment syncpoint: {}", +action.index);
|
Logger::Debug("Increment syncpoint: {}", +action.index);
|
||||||
channelCtx.executor.Submit([=, syncpoints = &this->syncpoints, index = 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) {
|
} else if (action.operation == Registers::Syncpoint::Operation::Wait) {
|
||||||
Logger::Debug("Wait syncpoint: {}, thresh: {}", +action.index, registers.syncpoint->payload);
|
Logger::Debug("Wait syncpoint: {}, thresh: {}", +action.index, registers.syncpoint->payload);
|
||||||
|
|
||||||
@ -29,7 +30,7 @@ namespace skyline::soc::gm20b::engine {
|
|||||||
|
|
||||||
channelCtx.executor.Submit();
|
channelCtx.executor.Submit();
|
||||||
channelCtx.Unlock();
|
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();
|
channelCtx.Lock();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -219,8 +219,9 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
ENGINE_CASE(syncpointAction, {
|
ENGINE_CASE(syncpointAction, {
|
||||||
Logger::Debug("Increment syncpoint: {}", static_cast<u16>(syncpointAction.id));
|
Logger::Debug("Increment syncpoint: {}", static_cast<u16>(syncpointAction.id));
|
||||||
channelCtx.executor.Submit([=, syncpoints = &this->syncpoints, index = 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, {
|
ENGINE_CASE(clearSurface, {
|
||||||
|
@ -30,7 +30,7 @@ namespace skyline::soc::host1x {
|
|||||||
u32 syncpointId{static_cast<u8>(argument)};
|
u32 syncpointId{static_cast<u8>(argument)};
|
||||||
Logger::Debug("Wait syncpoint: {}, thresh: {}", syncpointId, syncpointPayload);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,5 +62,18 @@ namespace skyline::soc::host1x {
|
|||||||
bool Wait(u32 threshold, std::chrono::steady_clock::duration timeout);
|
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>;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user