diff --git a/src/core/perf_stats.cpp b/src/core/perf_stats.cpp index 8d7724003..05449cd98 100644 --- a/src/core/perf_stats.cpp +++ b/src/core/perf_stats.cpp @@ -29,6 +29,8 @@ constexpr std::size_t IgnoreFrames = 5; namespace Core { +bool PerfStats::game_frames_updated = true; + PerfStats::PerfStats(u64 title_id) : title_id(title_id) {} PerfStats::~PerfStats() { @@ -109,6 +111,7 @@ void PerfStats::EndGameFrame() { std::scoped_lock lock{object_mutex}; game_frames += 1; + PerfStats::game_frames_updated = true; } double PerfStats::GetMeanFrametime() const { diff --git a/src/core/perf_stats.h b/src/core/perf_stats.h index de358de66..e335db7f3 100644 --- a/src/core/perf_stats.h +++ b/src/core/perf_stats.h @@ -120,6 +120,8 @@ public: artic_events.Set(event, set); } } + /// Boolean representing whether game_frames has been updated since last time it was presented + static bool game_frames_updated; private: mutable std::mutex object_mutex; diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index 760e1eaa6..a860039fd 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -236,23 +236,28 @@ void RendererVulkan::PrepareDraw(Frame* frame, const Layout::FramebufferLayout& void RendererVulkan::RenderToWindow(PresentWindow& window, const Layout::FramebufferLayout& layout, bool flipped) { - Frame* frame = window.GetRenderFrame(); + if (Core::PerfStats::game_frames_updated){ + Frame* frame = window.GetRenderFrame(); - if (layout.width != frame->width || layout.height != frame->height) { - window.WaitPresent(); - scheduler.Finish(); - window.RecreateFrame(frame, layout.width, layout.height); + if (layout.width != frame->width || layout.height != frame->height) { + window.WaitPresent(); + scheduler.Finish(); + window.RecreateFrame(frame, layout.width, layout.height); + } + + clear_color.float32[0] = Settings::values.bg_red.GetValue(); + clear_color.float32[1] = Settings::values.bg_green.GetValue(); + clear_color.float32[2] = Settings::values.bg_blue.GetValue(); + clear_color.float32[3] = 1.0f; + + DrawScreens(frame, layout, flipped); + scheduler.Flush(frame->render_ready); + window.Present(frame); + Core::PerfStats::game_frames_updated = false; + //LOG_INFO(Render_Vulkan, "Entered Present Thread"); + } else { + //LOG_INFO(Render_Vulkan, "Entered Skip Present Thread"); } - - clear_color.float32[0] = Settings::values.bg_red.GetValue(); - clear_color.float32[1] = Settings::values.bg_green.GetValue(); - clear_color.float32[2] = Settings::values.bg_blue.GetValue(); - clear_color.float32[3] = 1.0f; - - DrawScreens(frame, layout, flipped); - scheduler.Flush(frame->render_ready); - - window.Present(frame); } void RendererVulkan::LoadFBToScreenInfo(const Pica::FramebufferConfig& framebuffer, diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.h b/src/video_core/renderer_vulkan/renderer_vulkan.h index c236adc7e..39f918051 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.h +++ b/src/video_core/renderer_vulkan/renderer_vulkan.h @@ -134,7 +134,6 @@ private: DescriptorUpdateQueue update_queue; RasterizerVulkan rasterizer; std::unique_ptr secondary_present_window_ptr; - bool skip_frame_display; DescriptorHeap present_heap; vk::UniquePipelineLayout present_pipeline_layout; std::array present_pipelines; diff --git a/src/video_core/renderer_vulkan/vk_present_window.cpp b/src/video_core/renderer_vulkan/vk_present_window.cpp index 4d049d97d..2b7c765a3 100644 --- a/src/video_core/renderer_vulkan/vk_present_window.cpp +++ b/src/video_core/renderer_vulkan/vk_present_window.cpp @@ -290,6 +290,39 @@ void PresentWindow::Present(Frame* frame) { }); } +void PresentWindow::SkipPresent(Frame* frame) { + // Fix this later + if (!use_present_thread) { + scheduler.WaitWorker(); + CopyToSwapchain(frame); + free_queue.push(frame); + return; + } + + scheduler.Record([this, frame](vk::CommandBuffer) { + std::unique_lock lock{queue_mutex}; + //present_queue.push(frame); + frame_cv.notify_one(); + }); +} + +// Skip Present Bkup +// void PresentWindow::SkipPresent(Frame* frame) { +// if (!use_present_thread) { +// scheduler.WaitWorker(); +// CopyToSwapchain(frame); +// free_queue.push(frame); +// return; +// } + +// scheduler.Record([this, frame](vk::CommandBuffer) { +// std::unique_lock lock{queue_mutex}; +// present_queue.push(frame); +// frame_cv.notify_one(); +// }); +// } + + void PresentWindow::WaitPresent() { if (!use_present_thread) { return; diff --git a/src/video_core/renderer_vulkan/vk_present_window.h b/src/video_core/renderer_vulkan/vk_present_window.h index 012dbf81b..020e91a54 100644 --- a/src/video_core/renderer_vulkan/vk_present_window.h +++ b/src/video_core/renderer_vulkan/vk_present_window.h @@ -52,6 +52,9 @@ public: /// Queues the provided frame for presentation. void Present(Frame* frame); + /// Skip queuing the provided frame for presentation. + void SkipPresent(Frame* frame); + /// This is called to notify the rendering backend of a surface change void NotifySurfaceChanged();