@@ -33,7 +33,7 @@ namespace
3333 }
3434}
3535
36- void VKGSRender::reinitialize_swapchain ()
36+ bool VKGSRender::reinitialize_swapchain ()
3737{
3838 m_swapchain_dims.width = m_frame->client_width ();
3939 m_swapchain_dims.height = m_frame->client_height ();
@@ -44,7 +44,7 @@ void VKGSRender::reinitialize_swapchain()
4444 if (m_swapchain_dims.width == 0 || m_swapchain_dims.height == 0 )
4545 {
4646 swapchain_unavailable = true ;
47- return ;
47+ return false ;
4848 }
4949
5050 // NOTE: This operation will create a hard sync point
@@ -97,7 +97,7 @@ void VKGSRender::reinitialize_swapchain()
9797 {
9898 rsx_log.warning (" Swapchain initialization failed. Request ignored [%dx%d]" , m_swapchain_dims.width , m_swapchain_dims.height );
9999 swapchain_unavailable = true ;
100- return ;
100+ return false ;
101101 }
102102
103103 // Re-initialize CPU frame contexts
@@ -135,6 +135,7 @@ void VKGSRender::reinitialize_swapchain()
135135
136136 swapchain_unavailable = false ;
137137 should_reinitialize_swapchain = false ;
138+ return true ;
138139}
139140
140141void VKGSRender::present (vk::frame_context_t *ctx)
@@ -426,11 +427,32 @@ void VKGSRender::flip(const rsx::display_flip_info_t& info)
426427
427428 if (swapchain_unavailable || should_reinitialize_swapchain)
428429 {
429- reinitialize_swapchain ();
430+ // Reinitializing the swapchain is a failable operation. However, not all failures are fatal (e.g minimized window).
431+ // In the worst case, we can have the driver refuse to create the swapchain while we already deleted the previous one.
432+ // In such scenarios, we have to retry a few times before giving up as we cannot proceed without a swapchain.
433+ for (int i = 0 ; i < 10 ; ++i)
434+ {
435+ if (reinitialize_swapchain () || m_current_frame)
436+ {
437+ // If m_current_frame exists, then the initialization failure is non-fatal. Proceed as usual.
438+ break ;
439+ }
440+
441+ if (Emu.IsStopped ())
442+ {
443+ m_frame->flip (m_context);
444+ rsx::thread::flip (info);
445+ return ;
446+ }
447+
448+ std::this_thread::sleep_for (100ms);
449+ }
430450 }
431451
432452 m_profiler.start ();
433453
454+ ensure (m_current_frame, " Invalid swapchain setup. Resizing the game window failed." );
455+
434456 if (m_current_frame == &m_aux_frame_context)
435457 {
436458 m_current_frame = &m_frame_context_storage[m_current_queue_index];
@@ -582,6 +604,7 @@ void VKGSRender::flip(const rsx::display_flip_info_t& info)
582604 rsx_log.warning (" vkAcquireNextImageKHR failed with VK_ERROR_OUT_OF_DATE_KHR. Flip request ignored until surface is recreated." );
583605 swapchain_unavailable = true ;
584606 reinitialize_swapchain ();
607+ ensure (m_current_frame, " Could not reinitialize swapchain after VK_ERROR_OUT_OF_DATE_KHR signal!" );
585608 continue ;
586609 default :
587610 vk::die_with_error (status);
0 commit comments