mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 13:20:03 +00:00 
			
		
		
		
	renderer_vulkan: Address vulkan surface recreation issues
This commit is contained in:
		
							parent
							
								
									775ceac27d
								
							
						
					
					
						commit
						ffe0632608
					
				
					 6 changed files with 22 additions and 13 deletions
				
			
		|  | @ -27,14 +27,18 @@ static void UpdateLandscapeScreenLayout() { | ||||||
|             IDCache::GetNativeLibraryClass(), IDCache::GetLandscapeScreenLayout())); |             IDCache::GetNativeLibraryClass(), IDCache::GetLandscapeScreenLayout())); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void EmuWindow_Android::OnSurfaceChanged(ANativeWindow* surface) { | bool EmuWindow_Android::OnSurfaceChanged(ANativeWindow* surface) { | ||||||
|     render_window = surface; |     if (render_window == surface) { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|  |     render_window = surface; | ||||||
|     window_info.type = Frontend::WindowSystemType::Android; |     window_info.type = Frontend::WindowSystemType::Android; | ||||||
|     window_info.render_surface = surface; |     window_info.render_surface = surface; | ||||||
| 
 | 
 | ||||||
|     StopPresenting(); |     StopPresenting(); | ||||||
|     OnFramebufferSizeChanged(); |     OnFramebufferSizeChanged(); | ||||||
|  |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool EmuWindow_Android::OnTouchEvent(int x, int y, bool pressed) { | bool EmuWindow_Android::OnTouchEvent(int x, int y, bool pressed) { | ||||||
|  |  | ||||||
|  | @ -17,7 +17,7 @@ public: | ||||||
|     ~EmuWindow_Android(); |     ~EmuWindow_Android(); | ||||||
| 
 | 
 | ||||||
|     /// Called by the onSurfaceChanges() method to change the surface
 |     /// Called by the onSurfaceChanges() method to change the surface
 | ||||||
|     void OnSurfaceChanged(ANativeWindow* surface); |     bool OnSurfaceChanged(ANativeWindow* surface); | ||||||
| 
 | 
 | ||||||
|     /// Handles touch event that occur.(Touched or released)
 |     /// Handles touch event that occur.(Touched or released)
 | ||||||
|     bool OnTouchEvent(int x, int y, bool pressed); |     bool OnTouchEvent(int x, int y, bool pressed); | ||||||
|  |  | ||||||
|  | @ -288,12 +288,13 @@ void Java_org_citra_citra_1emu_NativeLibrary_surfaceChanged(JNIEnv* env, | ||||||
|                                                             jobject surf) { |                                                             jobject surf) { | ||||||
|     s_surf = ANativeWindow_fromSurface(env, surf); |     s_surf = ANativeWindow_fromSurface(env, surf); | ||||||
| 
 | 
 | ||||||
|  |     bool notify = false; | ||||||
|     if (window) { |     if (window) { | ||||||
|         window->OnSurfaceChanged(s_surf); |         notify = window->OnSurfaceChanged(s_surf); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     auto& system = Core::System::GetInstance(); |     auto& system = Core::System::GetInstance(); | ||||||
|     if (system.IsPoweredOn()) { |     if (notify && system.IsPoweredOn()) { | ||||||
|         system.GPU().Renderer().NotifySurfaceChanged(); |         system.GPU().Renderer().NotifySurfaceChanged(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME | ||||||
| distributionPath=wrapper/dists | distributionPath=wrapper/dists | ||||||
| zipStoreBase=GRADLE_USER_HOME | zipStoreBase=GRADLE_USER_HOME | ||||||
| zipStorePath=wrapper/dists | zipStorePath=wrapper/dists | ||||||
| distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip | distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip | ||||||
|  |  | ||||||
|  | @ -473,7 +473,7 @@ void PresentWindow::CopyToSwapchain(Frame* frame) { | ||||||
|         .pSignalSemaphores = &present_ready, |         .pSignalSemaphores = &present_ready, | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     std::scoped_lock submit_lock{scheduler.submit_mutex}; |     std::scoped_lock submit_lock{scheduler.submit_mutex, recreate_surface_mutex}; | ||||||
| 
 | 
 | ||||||
|     try { |     try { | ||||||
|         graphics_queue.submit(submit_info, frame->present_done); |         graphics_queue.submit(submit_info, frame->present_done); | ||||||
|  |  | ||||||
|  | @ -78,9 +78,13 @@ void Swapchain::Create(u32 width_, u32 height_, vk::SurfaceKHR surface_) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool Swapchain::AcquireNextImage() { | bool Swapchain::AcquireNextImage() { | ||||||
|  |     if (needs_recreation) { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     MICROPROFILE_SCOPE(Vulkan_Acquire); |     MICROPROFILE_SCOPE(Vulkan_Acquire); | ||||||
|     vk::Device device = instance.GetDevice(); |     const vk::Device device = instance.GetDevice(); | ||||||
|     vk::Result result = |     const vk::Result result = | ||||||
|         device.acquireNextImageKHR(swapchain, std::numeric_limits<u64>::max(), |         device.acquireNextImageKHR(swapchain, std::numeric_limits<u64>::max(), | ||||||
|                                    image_acquired[frame_index], VK_NULL_HANDLE, &image_index); |                                    image_acquired[frame_index], VK_NULL_HANDLE, &image_index); | ||||||
| 
 | 
 | ||||||
|  | @ -102,10 +106,6 @@ bool Swapchain::AcquireNextImage() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Swapchain::Present() { | void Swapchain::Present() { | ||||||
|     if (needs_recreation) { |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     const vk::PresentInfoKHR present_info = { |     const vk::PresentInfoKHR present_info = { | ||||||
|         .waitSemaphoreCount = 1, |         .waitSemaphoreCount = 1, | ||||||
|         .pWaitSemaphores = &present_ready[image_index], |         .pWaitSemaphores = &present_ready[image_index], | ||||||
|  | @ -119,6 +119,10 @@ void Swapchain::Present() { | ||||||
|         [[maybe_unused]] vk::Result result = instance.GetPresentQueue().presentKHR(present_info); |         [[maybe_unused]] vk::Result result = instance.GetPresentQueue().presentKHR(present_info); | ||||||
|     } catch (vk::OutOfDateKHRError&) { |     } catch (vk::OutOfDateKHRError&) { | ||||||
|         needs_recreation = true; |         needs_recreation = true; | ||||||
|  |         return; | ||||||
|  |     } catch (vk::SurfaceLostKHRError&) { | ||||||
|  |         needs_recreation = true; | ||||||
|  |         return; | ||||||
|     } catch (const vk::SystemError& err) { |     } catch (const vk::SystemError& err) { | ||||||
|         LOG_CRITICAL(Render_Vulkan, "Swapchain presentation failed {}", err.what()); |         LOG_CRITICAL(Render_Vulkan, "Swapchain presentation failed {}", err.what()); | ||||||
|         UNREACHABLE(); |         UNREACHABLE(); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue