added basic skip duplicate frames implementation

This commit is contained in:
KojoZero 2026-03-12 01:44:14 -07:00
parent e6a89e1b2c
commit 9b29295b07
6 changed files with 61 additions and 16 deletions

View File

@ -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 {

View File

@ -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;

View File

@ -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,

View File

@ -134,7 +134,6 @@ private:
DescriptorUpdateQueue update_queue;
RasterizerVulkan rasterizer;
std::unique_ptr<PresentWindow> secondary_present_window_ptr;
bool skip_frame_display;
DescriptorHeap present_heap;
vk::UniquePipelineLayout present_pipeline_layout;
std::array<vk::Pipeline, PRESENT_PIPELINES> present_pipelines;

View File

@ -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;

View File

@ -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();