diff options
| author | Scott Mansell <phiren@gmail.com> | 2023-02-03 17:42:47 +1300 |
|---|---|---|
| committer | Scott Mansell <phiren@gmail.com> | 2023-02-09 18:36:20 +1300 |
| commit | b2a31103b43c365d4c48a55b805001bfb07d974e (patch) | |
| tree | 96949bf616e98ac2602a61240f466f6d1f97a1c1 /Source/Core/VideoCommon/Present.cpp | |
| parent | 83b7b01265598067494eca228175e5b5805e36a2 (diff) | |
Presenter: Handle blanked frames correctly
Diffstat (limited to 'Source/Core/VideoCommon/Present.cpp')
| -rw-r--r-- | Source/Core/VideoCommon/Present.cpp | 46 |
1 files changed, 25 insertions, 21 deletions
diff --git a/Source/Core/VideoCommon/Present.cpp b/Source/Core/VideoCommon/Present.cpp index 1f3b8b8ad8..fa3be6acc5 100644 --- a/Source/Core/VideoCommon/Present.cpp +++ b/Source/Core/VideoCommon/Present.cpp @@ -66,54 +66,58 @@ bool Presenter::Initialize() bool Presenter::FetchXFB(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, u64 ticks) { ReleaseXFBContentLock(); + u64 old_xfb_id = m_last_xfb_id; - m_xfb_entry = - g_texture_cache->GetXFBTexture(xfb_addr, fb_width, fb_height, fb_stride, &m_xfb_rect); - bool is_duplicate = m_xfb_entry->id == m_last_xfb_id; - - m_xfb_entry->AcquireContentLock(); + if (fb_width == 0 || fb_height == 0) + { + // Game is blanking the screen + m_xfb_entry.reset(); + m_last_xfb_id = std::numeric_limits<u64>::max(); + } + else + { + m_xfb_entry = + g_texture_cache->GetXFBTexture(xfb_addr, fb_width, fb_height, fb_stride, &m_xfb_rect); + m_last_xfb_id = m_xfb_entry->id; + m_xfb_entry->AcquireContentLock(); + } m_last_xfb_addr = xfb_addr; m_last_xfb_ticks = ticks; m_last_xfb_width = fb_width; m_last_xfb_stride = fb_stride; m_last_xfb_height = fb_height; - m_last_xfb_id = m_xfb_entry->id; - return !is_duplicate; + return old_xfb_id == m_last_xfb_id; } void Presenter::ViSwap(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, u64 ticks) { - bool unique = FetchXFB(xfb_addr, fb_width, fb_stride, fb_height, ticks); + bool is_duplicate = FetchXFB(xfb_addr, fb_width, fb_stride, fb_height, ticks); PresentInfo present_info; present_info.emulated_timestamp = ticks; - if (unique) + present_info.present_count = m_present_count++; + if (is_duplicate) { - present_info.frame_count = m_frame_count++; - present_info.reason = PresentInfo::PresentReason::VideoInterface; + present_info.frame_count = m_frame_count - 1; // Previous frame + present_info.reason = PresentInfo::PresentReason::VideoInterfaceDuplicate; } else { - present_info.frame_count = m_frame_count - 1; // Previous frame - present_info.reason = PresentInfo::PresentReason::VideoInterfaceDuplicate; + present_info.frame_count = m_frame_count++; + present_info.reason = PresentInfo::PresentReason::VideoInterface; } - present_info.present_count = m_present_count; BeforePresentEvent::Trigger(present_info); - if (unique || !g_ActiveConfig.bSkipPresentingDuplicateXFBs) + if (!is_duplicate || !g_ActiveConfig.bSkipPresentingDuplicateXFBs) { Present(); ProcessFrameDumping(ticks); AfterPresentEvent::Trigger(present_info); } - else - { - g_gfx->Flush(); - } } void Presenter::ImmediateSwap(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, u64 ticks) @@ -121,7 +125,7 @@ void Presenter::ImmediateSwap(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_ FetchXFB(xfb_addr, fb_width, fb_stride, fb_height, ticks); PresentInfo present_info; - present_info.emulated_timestamp = ticks; + present_info.emulated_timestamp = ticks; // TODO: This should be the time of the next VI field present_info.frame_count = m_frame_count++; present_info.reason = PresentInfo::PresentReason::Immediate; present_info.present_count = m_present_count++; @@ -136,7 +140,7 @@ void Presenter::ImmediateSwap(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_ void Presenter::ProcessFrameDumping(u64 ticks) const { - if (g_frame_dumper->IsFrameDumping()) + if (g_frame_dumper->IsFrameDumping() && m_xfb_entry) { MathUtil::Rectangle<int> target_rect; if (!g_ActiveConfig.bInternalResolutionFrameDumps && !g_gfx->IsHeadless()) |
