From ceb5f5079c3efd8046ccf35bbc3507a4c190f355 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Tue, 4 Jun 2019 16:10:07 -0400 Subject: nvflinger: Implement swap intervals --- src/core/hle/service/nvflinger/buffer_queue.cpp | 3 ++- src/core/hle/service/nvflinger/buffer_queue.h | 3 ++- src/core/hle/service/nvflinger/nvflinger.cpp | 14 ++++++++++---- src/core/hle/service/nvflinger/nvflinger.h | 4 ++++ 4 files changed, 18 insertions(+), 6 deletions(-) (limited to 'src/core/hle/service/nvflinger') diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index 5731e815f..dca75c35e 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp @@ -63,7 +63,7 @@ const IGBPBuffer& BufferQueue::RequestBuffer(u32 slot) const { } void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform, - const Common::Rectangle& crop_rect) { + const Common::Rectangle& crop_rect, u32 swap_interval) { auto itr = std::find_if(queue.begin(), queue.end(), [&](const Buffer& buffer) { return buffer.slot == slot; }); ASSERT(itr != queue.end()); @@ -71,6 +71,7 @@ void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform, itr->status = Buffer::Status::Queued; itr->transform = transform; itr->crop_rect = crop_rect; + itr->swap_interval = swap_interval; } std::optional> BufferQueue::AcquireBuffer() { diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h index e1ccb6171..139b98b9f 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.h +++ b/src/core/hle/service/nvflinger/buffer_queue.h @@ -68,13 +68,14 @@ public: IGBPBuffer igbp_buffer; BufferTransformFlags transform; Common::Rectangle crop_rect; + u32 swap_interval; }; void SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer); std::optional DequeueBuffer(u32 width, u32 height); const IGBPBuffer& RequestBuffer(u32 slot) const; void QueueBuffer(u32 slot, BufferTransformFlags transform, - const Common::Rectangle& crop_rect); + const Common::Rectangle& crop_rect, u32 swap_interval); std::optional> AcquireBuffer(); void ReleaseBuffer(u32 slot); u32 Query(QueryType type); diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index 3c5c53e24..6d83535e7 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp @@ -37,15 +37,16 @@ NVFlinger::NVFlinger(Core::Timing::CoreTiming& core_timing) : core_timing{core_t displays.emplace_back(4, "Null"); // Schedule the screen composition events - const auto ticks = Settings::values.force_30fps_mode ? frame_ticks_30fps : frame_ticks; + //const auto ticks = Settings::values.force_30fps_mode ? frame_ticks_30fps : frame_ticks; composition_event = core_timing.RegisterEvent( - "ScreenComposition", [this, ticks](u64 userdata, s64 cycles_late) { + "ScreenComposition", [this](u64 userdata, s64 cycles_late) { Compose(); - this->core_timing.ScheduleEvent(ticks - cycles_late, composition_event); + const auto ticks = GetNextTicks(); + this->core_timing.ScheduleEvent(std::max(0LL,ticks - cycles_late), composition_event); }); - core_timing.ScheduleEvent(ticks, composition_event); + core_timing.ScheduleEvent(frame_ticks, composition_event); } NVFlinger::~NVFlinger() { @@ -206,8 +207,13 @@ void NVFlinger::Compose() { igbp_buffer.width, igbp_buffer.height, igbp_buffer.stride, buffer->get().transform, buffer->get().crop_rect); + swap_interval = buffer->get().swap_interval; buffer_queue.ReleaseBuffer(buffer->get().slot); } } +s64 NVFlinger::GetNextTicks() { + return (Core::Timing::BASE_CLOCK_RATE * (1LL << swap_interval)) / 120; +} + } // namespace Service::NVFlinger diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h index c0a83fffb..86b94302c 100644 --- a/src/core/hle/service/nvflinger/nvflinger.h +++ b/src/core/hle/service/nvflinger/nvflinger.h @@ -74,6 +74,8 @@ public: /// finished. void Compose(); + s64 GetNextTicks(); + private: /// Finds the display identified by the specified ID. VI::Display* FindDisplay(u64 display_id); @@ -98,6 +100,8 @@ private: /// layers. u32 next_buffer_queue_id = 1; + u32 swap_interval = 1; + /// Event that handles screen composition. Core::Timing::EventType* composition_event; -- cgit v1.2.3 From 737e978f5b1440a044ef90f346c8616c2de49a81 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Fri, 7 Jun 2019 11:34:55 -0400 Subject: nv_services: Correct buffer queue fencing and GPFifo fencing --- src/core/hle/service/nvflinger/buffer_queue.cpp | 9 ++++++--- src/core/hle/service/nvflinger/buffer_queue.h | 8 ++++++-- 2 files changed, 12 insertions(+), 5 deletions(-) (limited to 'src/core/hle/service/nvflinger') diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index dca75c35e..75e47b8c7 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp @@ -34,7 +34,8 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer) buffer_wait_event.writable->Signal(); } -std::optional BufferQueue::DequeueBuffer(u32 width, u32 height) { +std::optional> BufferQueue::DequeueBuffer(u32 width, + u32 height) { auto itr = std::find_if(queue.begin(), queue.end(), [&](const Buffer& buffer) { // Only consider free buffers. Buffers become free once again after they've been Acquired // and Released by the compositor, see the NVFlinger::Compose method. @@ -51,7 +52,7 @@ std::optional BufferQueue::DequeueBuffer(u32 width, u32 height) { } itr->status = Buffer::Status::Dequeued; - return itr->slot; + return {{itr->slot, &itr->multi_fence}}; } const IGBPBuffer& BufferQueue::RequestBuffer(u32 slot) const { @@ -63,7 +64,8 @@ const IGBPBuffer& BufferQueue::RequestBuffer(u32 slot) const { } void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform, - const Common::Rectangle& crop_rect, u32 swap_interval) { + const Common::Rectangle& crop_rect, u32 swap_interval, + Service::Nvidia::MultiFence& multi_fence) { auto itr = std::find_if(queue.begin(), queue.end(), [&](const Buffer& buffer) { return buffer.slot == slot; }); ASSERT(itr != queue.end()); @@ -72,6 +74,7 @@ void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform, itr->transform = transform; itr->crop_rect = crop_rect; itr->swap_interval = swap_interval; + itr->multi_fence = multi_fence; } std::optional> BufferQueue::AcquireBuffer() { diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h index 139b98b9f..c163e565c 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.h +++ b/src/core/hle/service/nvflinger/buffer_queue.h @@ -12,6 +12,7 @@ #include "common/swap.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/writable_event.h" +#include "core/hle/service/nvdrv/nvdata.h" namespace Service::NVFlinger { @@ -69,13 +70,16 @@ public: BufferTransformFlags transform; Common::Rectangle crop_rect; u32 swap_interval; + Service::Nvidia::MultiFence multi_fence; }; void SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer); - std::optional DequeueBuffer(u32 width, u32 height); + std::optional> DequeueBuffer(u32 width, + u32 height); const IGBPBuffer& RequestBuffer(u32 slot) const; void QueueBuffer(u32 slot, BufferTransformFlags transform, - const Common::Rectangle& crop_rect, u32 swap_interval); + const Common::Rectangle& crop_rect, u32 swap_interval, + Service::Nvidia::MultiFence& multi_fence); std::optional> AcquireBuffer(); void ReleaseBuffer(u32 slot); u32 Query(QueryType type); -- cgit v1.2.3 From ea975896242fba4a92d68c8fb45751e60ed826cc Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Mon, 10 Jun 2019 22:58:20 -0400 Subject: nvflinger: Acquire buffers in the same order as they were queued. --- src/core/hle/service/nvflinger/buffer_queue.cpp | 12 +++++++++--- src/core/hle/service/nvflinger/buffer_queue.h | 2 ++ 2 files changed, 11 insertions(+), 3 deletions(-) (limited to 'src/core/hle/service/nvflinger') diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index 75e47b8c7..d8aa3f1c0 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp @@ -75,12 +75,18 @@ void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform, itr->crop_rect = crop_rect; itr->swap_interval = swap_interval; itr->multi_fence = multi_fence; + queue_sequence.push_back(slot); } std::optional> BufferQueue::AcquireBuffer() { - auto itr = std::find_if(queue.begin(), queue.end(), [](const Buffer& buffer) { - return buffer.status == Buffer::Status::Queued; - }); + std::vector::iterator itr = queue.end(); + while (itr == queue.end() && !queue_sequence.empty()) { + u32 slot = queue_sequence.front(); + itr = std::find_if(queue.begin(), queue.end(), [&slot](const Buffer& buffer) { + return buffer.status == Buffer::Status::Queued && buffer.slot == slot; + }); + queue_sequence.pop_front(); + } if (itr == queue.end()) return {}; itr->status = Buffer::Status::Acquired; diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h index c163e565c..be993ee61 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.h +++ b/src/core/hle/service/nvflinger/buffer_queue.h @@ -6,6 +6,7 @@ #include #include +#include #include "common/common_funcs.h" #include "common/math_util.h" @@ -97,6 +98,7 @@ private: u64 layer_id; std::vector queue; + std::list queue_sequence; Kernel::EventPair buffer_wait_event; }; -- cgit v1.2.3 From 61697864c3c8abc35ce957f5f0a0dacd7a8e96f9 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Tue, 11 Jun 2019 17:56:36 -0400 Subject: nvflinger: Make the force 30 fps still force 30 fps --- src/core/hle/service/nvflinger/nvflinger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/hle/service/nvflinger') diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index 6d83535e7..a7937b490 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp @@ -42,7 +42,7 @@ NVFlinger::NVFlinger(Core::Timing::CoreTiming& core_timing) : core_timing{core_t composition_event = core_timing.RegisterEvent( "ScreenComposition", [this](u64 userdata, s64 cycles_late) { Compose(); - const auto ticks = GetNextTicks(); + const auto ticks = Settings::values.force_30fps_mode ? frame_ticks_30fps : GetNextTicks(); this->core_timing.ScheduleEvent(std::max(0LL,ticks - cycles_late), composition_event); }); -- cgit v1.2.3 From b391e5f6386eecf6170b544245e3e4e31427913c Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Tue, 18 Jun 2019 16:58:29 -0400 Subject: NVFlinger: Correct GCC compile error --- src/core/hle/service/nvflinger/buffer_queue.h | 2 +- src/core/hle/service/nvflinger/nvflinger.cpp | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src/core/hle/service/nvflinger') diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h index be993ee61..356bedb81 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.h +++ b/src/core/hle/service/nvflinger/buffer_queue.h @@ -4,9 +4,9 @@ #pragma once +#include #include #include -#include #include "common/common_funcs.h" #include "common/math_util.h" diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index a7937b490..70441f6a2 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp @@ -37,14 +37,14 @@ NVFlinger::NVFlinger(Core::Timing::CoreTiming& core_timing) : core_timing{core_t displays.emplace_back(4, "Null"); // Schedule the screen composition events - //const auto ticks = Settings::values.force_30fps_mode ? frame_ticks_30fps : frame_ticks; - - composition_event = core_timing.RegisterEvent( - "ScreenComposition", [this](u64 userdata, s64 cycles_late) { - Compose(); - const auto ticks = Settings::values.force_30fps_mode ? frame_ticks_30fps : GetNextTicks(); - this->core_timing.ScheduleEvent(std::max(0LL,ticks - cycles_late), composition_event); - }); + // const auto ticks = Settings::values.force_30fps_mode ? frame_ticks_30fps : frame_ticks; + + composition_event = core_timing.RegisterEvent("ScreenComposition", [this](u64 userdata, + s64 cycles_late) { + Compose(); + const auto ticks = Settings::values.force_30fps_mode ? frame_ticks_30fps : GetNextTicks(); + this->core_timing.ScheduleEvent(std::max(0LL, ticks - cycles_late), composition_event); + }); core_timing.ScheduleEvent(frame_ticks, composition_event); } -- cgit v1.2.3 From d20ede40b1e9cd0539982fb1feb3b13af3501ea2 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Tue, 18 Jun 2019 20:53:21 -0400 Subject: NVServices: Styling, define constructors as explicit and corrections --- src/core/hle/service/nvflinger/buffer_queue.cpp | 2 +- src/core/hle/service/nvflinger/nvflinger.cpp | 7 +++---- src/core/hle/service/nvflinger/nvflinger.h | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) (limited to 'src/core/hle/service/nvflinger') diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index d8aa3f1c0..ddc224f2c 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp @@ -79,7 +79,7 @@ void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform, } std::optional> BufferQueue::AcquireBuffer() { - std::vector::iterator itr = queue.end(); + auto itr = queue.end(); while (itr == queue.end() && !queue_sequence.empty()) { u32 slot = queue_sequence.front(); itr = std::find_if(queue.begin(), queue.end(), [&slot](const Buffer& buffer) { diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index 70441f6a2..f9db79370 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp @@ -37,8 +37,6 @@ NVFlinger::NVFlinger(Core::Timing::CoreTiming& core_timing) : core_timing{core_t displays.emplace_back(4, "Null"); // Schedule the screen composition events - // const auto ticks = Settings::values.force_30fps_mode ? frame_ticks_30fps : frame_ticks; - composition_event = core_timing.RegisterEvent("ScreenComposition", [this](u64 userdata, s64 cycles_late) { Compose(); @@ -212,8 +210,9 @@ void NVFlinger::Compose() { } } -s64 NVFlinger::GetNextTicks() { - return (Core::Timing::BASE_CLOCK_RATE * (1LL << swap_interval)) / 120; +s64 NVFlinger::GetNextTicks() const { + constexpr s64 max_hertz = 120LL; + return (Core::Timing::BASE_CLOCK_RATE * (1LL << swap_interval)) / max_hertz; } } // namespace Service::NVFlinger diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h index 86b94302c..988be8726 100644 --- a/src/core/hle/service/nvflinger/nvflinger.h +++ b/src/core/hle/service/nvflinger/nvflinger.h @@ -74,7 +74,7 @@ public: /// finished. void Compose(); - s64 GetNextTicks(); + s64 GetNextTicks() const; private: /// Finds the display identified by the specified ID. -- cgit v1.2.3 From f3a39e0c9ce8468859da12e35a52fa088e264d28 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Mon, 1 Jul 2019 11:10:27 -0400 Subject: NVServices: Address Feedback --- src/core/hle/service/nvflinger/buffer_queue.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/core/hle/service/nvflinger') diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index ddc224f2c..e1a07d3ee 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp @@ -80,6 +80,7 @@ void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform, std::optional> BufferQueue::AcquireBuffer() { auto itr = queue.end(); + // Iterate to find a queued buffer matching the requested slot. while (itr == queue.end() && !queue_sequence.empty()) { u32 slot = queue_sequence.front(); itr = std::find_if(queue.begin(), queue.end(), [&slot](const Buffer& buffer) { -- cgit v1.2.3