mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-01 15:02:40 +00:00
libraries: videoout: better flip status handling
This commit is contained in:
parent
c94190b69b
commit
01e66bb548
@ -174,14 +174,19 @@ std::chrono::microseconds VideoOutDriver::Flip(const Request& req) {
|
|||||||
|
|
||||||
// Update flip status.
|
// Update flip status.
|
||||||
auto* port = req.port;
|
auto* port = req.port;
|
||||||
auto& flip_status = port->flip_status;
|
{
|
||||||
flip_status.count++;
|
std::unique_lock lock{port->port_mutex};
|
||||||
flip_status.processTime = Libraries::Kernel::sceKernelGetProcessTime();
|
auto& flip_status = port->flip_status;
|
||||||
flip_status.tsc = Libraries::Kernel::sceKernelReadTsc();
|
flip_status.count++;
|
||||||
flip_status.submitTsc = Libraries::Kernel::sceKernelReadTsc();
|
flip_status.processTime = Libraries::Kernel::sceKernelGetProcessTime();
|
||||||
flip_status.flipArg = req.flip_arg;
|
flip_status.tsc = Libraries::Kernel::sceKernelReadTsc();
|
||||||
flip_status.currentBuffer = req.index;
|
flip_status.flipArg = req.flip_arg;
|
||||||
flip_status.flipPendingNum = static_cast<int>(requests.size());
|
flip_status.currentBuffer = req.index;
|
||||||
|
if (req.eop) {
|
||||||
|
--flip_status.gcQueueNum;
|
||||||
|
}
|
||||||
|
--flip_status.flipPendingNum;
|
||||||
|
}
|
||||||
|
|
||||||
// Trigger flip events for the port.
|
// Trigger flip events for the port.
|
||||||
for (auto& event : port->flip_events) {
|
for (auto& event : port->flip_events) {
|
||||||
@ -203,15 +208,18 @@ std::chrono::microseconds VideoOutDriver::Flip(const Request& req) {
|
|||||||
|
|
||||||
bool VideoOutDriver::SubmitFlip(VideoOutPort* port, s32 index, s64 flip_arg,
|
bool VideoOutDriver::SubmitFlip(VideoOutPort* port, s32 index, s64 flip_arg,
|
||||||
bool is_eop /*= false*/) {
|
bool is_eop /*= false*/) {
|
||||||
u32 num_requests_pending{};
|
|
||||||
{
|
{
|
||||||
std::scoped_lock lock{mutex};
|
std::unique_lock lock{port->port_mutex};
|
||||||
num_requests_pending = requests.size();
|
if (index != -1 && port->flip_status.flipPendingNum >= port->NumRegisteredBuffers()) {
|
||||||
}
|
LOG_ERROR(Lib_VideoOut, "Flip queue is full");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (index != -1 && num_requests_pending >= port->NumRegisteredBuffers()) {
|
if (is_eop) {
|
||||||
LOG_ERROR(Lib_VideoOut, "Flip queue is full");
|
++port->flip_status.gcQueueNum;
|
||||||
return false;
|
}
|
||||||
|
++port->flip_status.flipPendingNum; // integral GPU and CPU pending flips counter
|
||||||
|
port->flip_status.submitTsc = Libraries::Kernel::sceKernelReadTsc();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_eop) {
|
if (!is_eop) {
|
||||||
@ -226,9 +234,6 @@ bool VideoOutDriver::SubmitFlip(VideoOutPort* port, s32 index, s64 flip_arg,
|
|||||||
SubmitFlipInternal(port, index, flip_arg, is_eop);
|
SubmitFlipInternal(port, index, flip_arg, is_eop);
|
||||||
}
|
}
|
||||||
|
|
||||||
port->flip_status.flipPendingNum = num_requests_pending + 1;
|
|
||||||
port->flip_status.gcQueueNum = 0;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,7 +254,6 @@ void VideoOutDriver::SubmitFlipInternal(VideoOutPort* port, s32 index, s64 flip_
|
|||||||
.port = port,
|
.port = port,
|
||||||
.index = index,
|
.index = index,
|
||||||
.flip_arg = flip_arg,
|
.flip_arg = flip_arg,
|
||||||
.submit_tsc = Libraries::Kernel::sceKernelReadTsc(),
|
|
||||||
.eop = is_eop,
|
.eop = is_eop,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ struct VideoOutPort {
|
|||||||
std::vector<Kernel::SceKernelEqueue> flip_events;
|
std::vector<Kernel::SceKernelEqueue> flip_events;
|
||||||
std::vector<Kernel::SceKernelEqueue> vblank_events;
|
std::vector<Kernel::SceKernelEqueue> vblank_events;
|
||||||
std::mutex vo_mutex;
|
std::mutex vo_mutex;
|
||||||
|
std::mutex port_mutex;
|
||||||
std::condition_variable vo_cv;
|
std::condition_variable vo_cv;
|
||||||
std::condition_variable vblank_cv;
|
std::condition_variable vblank_cv;
|
||||||
int flip_rate = 0;
|
int flip_rate = 0;
|
||||||
@ -93,7 +94,6 @@ private:
|
|||||||
VideoOutPort* port;
|
VideoOutPort* port;
|
||||||
s32 index;
|
s32 index;
|
||||||
s64 flip_arg;
|
s64 flip_arg;
|
||||||
u64 submit_tsc;
|
|
||||||
bool eop;
|
bool eop;
|
||||||
|
|
||||||
operator bool() const noexcept {
|
operator bool() const noexcept {
|
||||||
|
@ -113,7 +113,9 @@ s32 PS4_SYSV_ABI sceVideoOutSetFlipRate(s32 handle, s32 rate) {
|
|||||||
|
|
||||||
s32 PS4_SYSV_ABI sceVideoOutIsFlipPending(s32 handle) {
|
s32 PS4_SYSV_ABI sceVideoOutIsFlipPending(s32 handle) {
|
||||||
LOG_INFO(Lib_VideoOut, "called");
|
LOG_INFO(Lib_VideoOut, "called");
|
||||||
s32 pending = driver->GetPort(handle)->flip_status.flipPendingNum;
|
auto* port = driver->GetPort(handle);
|
||||||
|
std::unique_lock lock{port->port_mutex};
|
||||||
|
s32 pending = port->flip_status.flipPendingNum;
|
||||||
return pending;
|
return pending;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,6 +163,7 @@ s32 PS4_SYSV_ABI sceVideoOutGetFlipStatus(s32 handle, FlipStatus* status) {
|
|||||||
return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE;
|
return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_lock lock{port->port_mutex};
|
||||||
*status = port->flip_status;
|
*status = port->flip_status;
|
||||||
|
|
||||||
LOG_INFO(Lib_VideoOut,
|
LOG_INFO(Lib_VideoOut,
|
||||||
|
Loading…
Reference in New Issue
Block a user