diff options
| -rw-r--r-- | src/android/app/src/main/jni/native.cpp | 1 | ||||
| -rw-r--r-- | src/video_core/renderer_base.h | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/renderer_vulkan.h | 4 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_present_manager.cpp | 67 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_present_manager.h | 10 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_wrapper.h | 3 | 
6 files changed, 36 insertions, 52 deletions
| diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index 9cf71680c..598f4e8bf 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp @@ -218,7 +218,6 @@ public:              return;          }          m_window->OnSurfaceChanged(m_native_window); -        m_system.Renderer().NotifySurfaceChanged();      }      void ConfigureFilesystemProvider(const std::string& filepath) { diff --git a/src/video_core/renderer_base.h b/src/video_core/renderer_base.h index 3e12a8813..78ea5208b 100644 --- a/src/video_core/renderer_base.h +++ b/src/video_core/renderer_base.h @@ -89,9 +89,6 @@ public:      void RequestScreenshot(void* data, std::function<void(bool)> callback,                             const Layout::FramebufferLayout& layout); -    /// This is called to notify the rendering backend of a surface change -    virtual void NotifySurfaceChanged() {} -  protected:      Core::Frontend::EmuWindow& render_window; ///< Reference to the render window handle.      std::unique_ptr<Core::Frontend::GraphicsContext> context; diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.h b/src/video_core/renderer_vulkan/renderer_vulkan.h index 590bc1c64..14e257cf7 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.h +++ b/src/video_core/renderer_vulkan/renderer_vulkan.h @@ -56,10 +56,6 @@ public:          return device.GetDriverName();      } -    void NotifySurfaceChanged() override { -        present_manager.NotifySurfaceChanged(); -    } -  private:      void Report() const; diff --git a/src/video_core/renderer_vulkan/vk_present_manager.cpp b/src/video_core/renderer_vulkan/vk_present_manager.cpp index d681bd22a..2ef36583b 100644 --- a/src/video_core/renderer_vulkan/vk_present_manager.cpp +++ b/src/video_core/renderer_vulkan/vk_present_manager.cpp @@ -103,8 +103,7 @@ PresentManager::PresentManager(const vk::Instance& instance_,        surface{surface_}, blit_supported{CanBlitToSwapchain(device.GetPhysical(),                                                             swapchain.GetImageViewFormat())},        use_present_thread{Settings::values.async_presentation.GetValue()}, -      image_count{swapchain.GetImageCount()}, last_render_surface{ -                                                  render_window_.GetWindowInfo().render_surface} { +      image_count{swapchain.GetImageCount()} {      auto& dld = device.GetLogical();      cmdpool = dld.CreateCommandPool({ @@ -289,44 +288,36 @@ void PresentManager::PresentThread(std::stop_token token) {      }  } -void PresentManager::NotifySurfaceChanged() { -#ifdef ANDROID -    std::scoped_lock lock{recreate_surface_mutex}; -    recreate_surface_cv.notify_one(); -#endif +void PresentManager::RecreateSwapchain(Frame* frame) { +    swapchain.Create(*surface, frame->width, frame->height, frame->is_srgb); +    image_count = swapchain.GetImageCount();  }  void PresentManager::CopyToSwapchain(Frame* frame) { -    MICROPROFILE_SCOPE(Vulkan_CopyToSwapchain); - -    const auto recreate_swapchain = [&] { -        swapchain.Create(*surface, frame->width, frame->height, frame->is_srgb); -        image_count = swapchain.GetImageCount(); -    }; - -#ifdef ANDROID -    std::unique_lock lock{recreate_surface_mutex}; - -    const auto needs_recreation = [&] { -        if (last_render_surface != render_window.GetWindowInfo().render_surface) { -            return true; -        } -        if (swapchain.NeedsRecreation(frame->is_srgb)) { -            return true; +    bool requires_recreation = false; + +    while (true) { +        try { +            // Recreate surface and swapchain if needed. +            if (requires_recreation) { +                surface = CreateSurface(instance, render_window.GetWindowInfo()); +                RecreateSwapchain(frame); +            } + +            // Draw to swapchain. +            return CopyToSwapchainImpl(frame); +        } catch (const vk::Exception& except) { +            if (except.GetResult() != VK_ERROR_SURFACE_LOST_KHR) { +                throw; +            } + +            requires_recreation = true;          } -        return false; -    }; - -    recreate_surface_cv.wait_for(lock, std::chrono::milliseconds(400), -                                 [&]() { return !needs_recreation(); }); - -    // If the frontend recreated the surface, recreate the renderer surface and swapchain. -    if (last_render_surface != render_window.GetWindowInfo().render_surface) { -        last_render_surface = render_window.GetWindowInfo().render_surface; -        surface = CreateSurface(instance, render_window.GetWindowInfo()); -        recreate_swapchain();      } -#endif +} + +void PresentManager::CopyToSwapchainImpl(Frame* frame) { +    MICROPROFILE_SCOPE(Vulkan_CopyToSwapchain);      // If the size or colorspace of the incoming frames has changed, recreate the swapchain      // to account for that. @@ -334,11 +325,11 @@ void PresentManager::CopyToSwapchain(Frame* frame) {      const bool size_changed =          swapchain.GetWidth() != frame->width || swapchain.GetHeight() != frame->height;      if (srgb_changed || size_changed) { -        recreate_swapchain(); +        RecreateSwapchain(frame);      }      while (swapchain.AcquireNextImage()) { -        recreate_swapchain(); +        RecreateSwapchain(frame);      }      const vk::CommandBuffer cmdbuf{frame->cmdbuf}; @@ -488,4 +479,4 @@ void PresentManager::CopyToSwapchain(Frame* frame) {      swapchain.Present(render_semaphore);  } -} // namespace Vulkan
\ No newline at end of file +} // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_present_manager.h b/src/video_core/renderer_vulkan/vk_present_manager.h index 83e859416..a3d825fe6 100644 --- a/src/video_core/renderer_vulkan/vk_present_manager.h +++ b/src/video_core/renderer_vulkan/vk_present_manager.h @@ -54,14 +54,15 @@ public:      /// Waits for the present thread to finish presenting all queued frames.      void WaitPresent(); -    /// This is called to notify the rendering backend of a surface change -    void NotifySurfaceChanged(); -  private:      void PresentThread(std::stop_token token);      void CopyToSwapchain(Frame* frame); +    void CopyToSwapchainImpl(Frame* frame); + +    void RecreateSwapchain(Frame* frame); +  private:      const vk::Instance& instance;      Core::Frontend::EmuWindow& render_window; @@ -76,16 +77,13 @@ private:      std::queue<Frame*> free_queue;      std::condition_variable_any frame_cv;      std::condition_variable free_cv; -    std::condition_variable recreate_surface_cv;      std::mutex swapchain_mutex; -    std::mutex recreate_surface_mutex;      std::mutex queue_mutex;      std::mutex free_mutex;      std::jthread present_thread;      bool blit_supported;      bool use_present_thread;      std::size_t image_count{}; -    void* last_render_surface{};  };  } // namespace Vulkan diff --git a/src/video_core/vulkan_common/vulkan_wrapper.h b/src/video_core/vulkan_common/vulkan_wrapper.h index 1e3c0fa64..0487cd3b6 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.h +++ b/src/video_core/vulkan_common/vulkan_wrapper.h @@ -117,6 +117,9 @@ public:      virtual ~Exception() = default;      const char* what() const noexcept override; +    VkResult GetResult() const noexcept { +        return result; +    }  private:      VkResult result; | 
