summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon
diff options
context:
space:
mode:
authorScott Mansell <phiren@gmail.com>2023-01-28 21:30:56 +1300
committerScott Mansell <phiren@gmail.com>2023-01-31 19:41:24 +1300
commit18c799f0b6291df2a994489ebcd34d3dfa290ff3 (patch)
treea104e0edb18131f4b45d45a59cdffa8aeacf8dbf /Source/Core/VideoCommon
parent06ae08ca8b9acd77022585c3a766a8d26e61793a (diff)
Present: Set surface info before initializing ImGui
Otherwise you get subtle bugs in vulkan that take hours to track down.
Diffstat (limited to 'Source/Core/VideoCommon')
-rw-r--r--Source/Core/VideoCommon/Present.cpp76
1 files changed, 46 insertions, 30 deletions
diff --git a/Source/Core/VideoCommon/Present.cpp b/Source/Core/VideoCommon/Present.cpp
index a89b41b1dd..55df419d0c 100644
--- a/Source/Core/VideoCommon/Present.cpp
+++ b/Source/Core/VideoCommon/Present.cpp
@@ -40,17 +40,20 @@ bool Presenter::Initialize()
{
UpdateDrawRectangle();
- m_post_processor = std::make_unique<VideoCommon::PostProcessing>();
- if (!m_post_processor->Initialize(m_backbuffer_format))
- return false;
-
- m_onscreen_ui = std::make_unique<OnScreenUI>();
- if (!m_onscreen_ui->Initialize(m_backbuffer_width, m_backbuffer_height, m_backbuffer_scale))
- return false;
-
if (!g_gfx->IsHeadless())
+ {
SetBackbuffer(g_gfx->GetSurfaceInfo());
+ m_post_processor = std::make_unique<VideoCommon::PostProcessing>();
+ if (!m_post_processor->Initialize(m_backbuffer_format))
+ return false;
+
+ m_onscreen_ui = std::make_unique<OnScreenUI>();
+ if (!m_onscreen_ui->Initialize(m_backbuffer_width, m_backbuffer_height, m_backbuffer_scale))
+ return false;
+
+ }
+
return true;
}
@@ -74,7 +77,7 @@ void Presenter::CheckForConfigChanges(u32 changed_bits)
{
// Check for post-processing shader changes. Done up here as it doesn't affect anything outside
// the post-processor. Note that options are applied every frame, so no need to check those.
- if (m_post_processor->GetConfig()->GetShader() != g_ActiveConfig.sPostProcessingShader)
+ if (m_post_processor && m_post_processor->GetConfig()->GetShader() != g_ActiveConfig.sPostProcessingShader)
{
// The existing shader must not be in use when it's destroyed
g_gfx->WaitForGPUIdle();
@@ -86,8 +89,10 @@ void Presenter::CheckForConfigChanges(u32 changed_bits)
// rendering the UI.
if (changed_bits & ConfigChangeBits::CONFIG_CHANGE_BIT_STEREO_MODE)
{
- m_onscreen_ui->RecompileImGuiPipeline();
- m_post_processor->RecompilePipeline();
+ if (m_onscreen_ui)
+ m_onscreen_ui->RecompileImGuiPipeline();
+ if (m_post_processor)
+ m_post_processor->RecompilePipeline();
}
}
@@ -425,6 +430,7 @@ bool Presenter::SubmitXFB(RcTcacheEntry xfb_entry, MathUtil::Rectangle<int>& xfb
m_xfb_entry = std::move(xfb_entry);
m_xfb_rect = xfb_rect;
bool is_duplicate_frame = m_last_xfb_id == m_xfb_entry->id;
+ m_last_xfb_id = m_xfb_entry->id;
if (!is_duplicate_frame || !g_ActiveConfig.bSkipPresentingDuplicateXFBs)
{
@@ -455,7 +461,8 @@ bool Presenter::SubmitXFB(RcTcacheEntry xfb_entry, MathUtil::Rectangle<int>& xfb
void Presenter::Present()
{
- m_last_xfb_id = m_xfb_entry->id;
+ if (g_gfx->IsHeadless() || (!m_onscreen_ui && !m_xfb_entry))
+ return;
if (!g_gfx->SupportsUtilityDrawing())
{
@@ -470,60 +477,69 @@ void Presenter::Present()
// with the loader, and it has not been unmapped yet. Force a pipeline flush to avoid this.
g_vertex_manager->Flush();
- // Render any UI elements to the draw list.
- m_onscreen_ui->Finalize();
+ UpdateDrawRectangle();
- // Render the XFB to the screen.
g_gfx->BeginUtilityDrawing();
- if (!g_gfx->IsHeadless())
- {
- g_gfx->BindBackbuffer({{0.0f, 0.0f, 0.0f, 1.0f}});
-
- UpdateDrawRectangle();
+ g_gfx->BindBackbuffer({{0.0f, 0.0f, 0.0f, 1.0f}});
+ // Render the XFB to the screen.
+ if (m_xfb_entry)
+ {
// Adjust the source rectangle instead of using an oversized viewport to render the XFB.
auto render_target_rc = GetTargetRectangle();
auto render_source_rc = m_xfb_rect;
AdjustRectanglesToFitBounds(&render_target_rc, &render_source_rc, m_backbuffer_width,
m_backbuffer_height);
RenderXFBToScreen(render_target_rc, m_xfb_entry->texture.get(), render_source_rc);
+ }
+ if (m_onscreen_ui)
+ {
+ m_onscreen_ui->Finalize();
m_onscreen_ui->DrawImGui();
+ }
- // Present to the window system.
- {
- std::lock_guard<std::mutex> guard(m_swap_mutex);
- g_gfx->PresentBackbuffer();
- }
+ // Present to the window system.
+ {
+ std::lock_guard<std::mutex> guard(m_swap_mutex);
+ g_gfx->PresentBackbuffer();
+ }
+ if (m_xfb_entry)
+ {
// Update the window size based on the frame that was just rendered.
// Due to depending on guest state, we need to call this every frame.
SetWindowSize(m_xfb_rect.GetWidth(), m_xfb_rect.GetHeight());
}
- m_onscreen_ui->BeginImGuiFrame(m_backbuffer_width, m_backbuffer_height);
+ if (m_onscreen_ui)
+ m_onscreen_ui->BeginImGuiFrame(m_backbuffer_width, m_backbuffer_height);
g_gfx->EndUtilityDrawing();
}
void Presenter::SetKeyMap(std::span<std::array<int, 2>> key_map)
{
- m_onscreen_ui->SetKeyMap(key_map);
+ if (m_onscreen_ui)
+ m_onscreen_ui->SetKeyMap(key_map);
}
void Presenter::SetKey(u32 key, bool is_down, const char* chars)
{
- m_onscreen_ui->SetKey(key, is_down, chars);
+ if (m_onscreen_ui)
+ m_onscreen_ui->SetKey(key, is_down, chars);
}
void Presenter::SetMousePos(float x, float y)
{
- m_onscreen_ui->SetMousePos(x, y);
+ if (m_onscreen_ui)
+ m_onscreen_ui->SetMousePos(x, y);
}
void Presenter::SetMousePress(u32 button_mask)
{
- m_onscreen_ui->SetMousePress(button_mask);
+ if (m_onscreen_ui)
+ m_onscreen_ui->SetMousePress(button_mask);
}
} // namespace VideoCommon