mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-27 21:36:54 +01:00
graphics: stall waitUntilSafeForRendering in its command processor instead of the GPU thread
This commit is contained in:
@@ -221,7 +221,7 @@ public:
|
||||
void WaitForSubmitSlot(VideoOutConfig& cfg);
|
||||
bool Flip(uint32_t micros);
|
||||
void GetFlipStatus(VideoOutConfig& cfg, VideoOutFlipStatus& out);
|
||||
void Wait(VideoOutConfig& cfg, int index);
|
||||
bool IsSafeForRendering(VideoOutConfig& cfg, int index);
|
||||
|
||||
private:
|
||||
enum class RequestState { Reserved, Recording, Ready, Presenting };
|
||||
@@ -240,6 +240,7 @@ private:
|
||||
Graphics::Presenter::Frame* frame;
|
||||
bool premultiplied_alpha;
|
||||
};
|
||||
void SignalDoneLocked();
|
||||
|
||||
Graphics::Presenter& m_presenter;
|
||||
Common::Mutex m_mutex;
|
||||
@@ -250,6 +251,7 @@ private:
|
||||
std::list<Request> m_cpu_requests;
|
||||
std::list<Request> m_cancelled_requests;
|
||||
bool m_processing = false;
|
||||
bool m_gpu_waiting = false;
|
||||
uint64_t m_next_request_id = 1;
|
||||
};
|
||||
|
||||
@@ -953,7 +955,7 @@ bool FlipQueue::Reserve(VideoOutConfig& cfg, int index, int64_t flip_arg, FlipRe
|
||||
}
|
||||
}
|
||||
}
|
||||
m_done_cond_var.SignalAll();
|
||||
SignalDoneLocked();
|
||||
}
|
||||
if (cfg.flip_status.flipPendingNum >= VIDEO_OUT_FLIP_QUEUE_CAPACITY) {
|
||||
Common::DebugCounters::Add(Common::DebugCounters::Counter::FlipsRejected);
|
||||
@@ -1033,7 +1035,7 @@ void FlipQueue::Cancel(VideoOutConfig& cfg) {
|
||||
it = queue->erase(it);
|
||||
}
|
||||
}
|
||||
m_done_cond_var.SignalAll();
|
||||
SignalDoneLocked();
|
||||
m_submit_slot_cond_var.SignalAll();
|
||||
m_submit_cond_var.SignalAll();
|
||||
m_mutex.Unlock();
|
||||
@@ -1205,19 +1207,26 @@ void FlipQueue::WaitForSubmitSlot(VideoOutConfig& cfg) {
|
||||
}
|
||||
}
|
||||
|
||||
void FlipQueue::Wait(VideoOutConfig& cfg, int index) {
|
||||
Common::LockGuard lock(m_mutex);
|
||||
|
||||
auto has_request = [this, &cfg, index] {
|
||||
auto matches = [&cfg, index](const auto& r) { return r.cfg == &cfg && r.index == index; };
|
||||
return std::any_of(m_requests.begin(), m_requests.end(), matches) ||
|
||||
std::any_of(m_cpu_requests.begin(), m_cpu_requests.end(), matches);
|
||||
};
|
||||
while (has_request()) {
|
||||
m_done_cond_var.Wait(&m_mutex);
|
||||
void FlipQueue::SignalDoneLocked() {
|
||||
m_done_cond_var.SignalAll();
|
||||
// A stalled GPU cannot drain and shut down without re-checking under m_mutex, so it is alive here.
|
||||
if (m_gpu_waiting) {
|
||||
m_gpu_waiting = false;
|
||||
m_presenter.Renderer().GetGpu().Wake();
|
||||
}
|
||||
}
|
||||
|
||||
// A display buffer is safe for rendering once it is neither displayed nor waiting to be.
|
||||
bool FlipQueue::IsSafeForRendering(VideoOutConfig& cfg, int index) {
|
||||
Common::LockGuard lock(m_mutex);
|
||||
auto matches = [&cfg, index](const auto& r) { return r.cfg == &cfg && r.index == index; };
|
||||
const bool safe = cfg.flip_status.currentBuffer != index &&
|
||||
std::none_of(m_requests.begin(), m_requests.end(), matches) &&
|
||||
std::none_of(m_cpu_requests.begin(), m_cpu_requests.end(), matches);
|
||||
m_gpu_waiting = !safe;
|
||||
return safe;
|
||||
}
|
||||
|
||||
bool FlipQueue::Flip(uint32_t micros) {
|
||||
KYTY_PROFILER_BLOCK("FlipQueue::Flip");
|
||||
|
||||
@@ -1311,7 +1320,7 @@ bool FlipQueue::Flip(uint32_t micros) {
|
||||
it = m_requests.erase(it);
|
||||
}
|
||||
m_processing = false;
|
||||
m_done_cond_var.SignalAll();
|
||||
SignalDoneLocked();
|
||||
m_submit_slot_cond_var.SignalAll();
|
||||
m_mutex.Unlock();
|
||||
for (size_t i = count; i != 0; i--) {
|
||||
@@ -1694,12 +1703,12 @@ void VideoOutDriver::WaitForSubmitSlot(int handle) {
|
||||
m_impl->GetFlipQueue().WaitForSubmitSlot(*cfg);
|
||||
}
|
||||
|
||||
void VideoOutDriver::WaitFlipDone(int handle, int index) {
|
||||
bool VideoOutDriver::IsSafeForRendering(int handle, int index) {
|
||||
auto* ctx = m_impl->Get(handle);
|
||||
EXIT_IF(ctx == nullptr);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(!IsValidBufferIndex(index));
|
||||
m_impl->GetFlipQueue().Wait(*ctx, index);
|
||||
return m_impl->GetFlipQueue().IsSafeForRendering(*ctx, index);
|
||||
}
|
||||
|
||||
KYTY_SYSV_ABI int VideoOutGetFlipStatus(int handle, VideoOutFlipStatus* status) {
|
||||
|
||||
@@ -38,7 +38,7 @@ public:
|
||||
void CompleteFlip(uint64_t request_id);
|
||||
void SubmitFlipPreparation(uint64_t request_id);
|
||||
void WaitForSubmitSlot(int handle);
|
||||
void WaitFlipDone(int handle, int index);
|
||||
[[nodiscard]] bool IsSafeForRendering(int handle, int index);
|
||||
|
||||
[[nodiscard]] Impl& State() noexcept;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user