diff options
| author | 2023-05-03 21:54:31 -0700 | |
|---|---|---|
| committer | 2023-06-03 00:05:59 -0700 | |
| commit | 117bc2ae6c9683fd4530cfddb33b4ffc9419cff7 (patch) | |
| tree | abe55ef4689045d68e88938078544fbdf0356c46 /src/video_core | |
| parent | android: Game data cache (diff) | |
| download | yuzu-117bc2ae6c9683fd4530cfddb33b4ffc9419cff7.tar.gz yuzu-117bc2ae6c9683fd4530cfddb33b4ffc9419cff7.tar.xz yuzu-117bc2ae6c9683fd4530cfddb33b4ffc9419cff7.zip | |
android: vulkan: Recreate surface after suspension & adapt to async. presentation.
Diffstat (limited to 'src/video_core')
5 files changed, 35 insertions, 15 deletions
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index 30dc69f13..77128c6e2 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp | |||
| @@ -93,7 +93,8 @@ RendererVulkan::RendererVulkan(Core::TelemetrySession& telemetry_session_, | |||
| 93 | state_tracker(), scheduler(device, state_tracker), | 93 | state_tracker(), scheduler(device, state_tracker), |
| 94 | swapchain(*surface, device, scheduler, render_window.GetFramebufferLayout().width, | 94 | swapchain(*surface, device, scheduler, render_window.GetFramebufferLayout().width, |
| 95 | render_window.GetFramebufferLayout().height, false), | 95 | render_window.GetFramebufferLayout().height, false), |
| 96 | present_manager(render_window, device, memory_allocator, scheduler, swapchain), | 96 | present_manager(instance, render_window, device, memory_allocator, scheduler, swapchain, |
| 97 | surface), | ||
| 97 | blit_screen(cpu_memory, render_window, device, memory_allocator, swapchain, present_manager, | 98 | blit_screen(cpu_memory, render_window, device, memory_allocator, swapchain, present_manager, |
| 98 | scheduler, screen_info), | 99 | scheduler, screen_info), |
| 99 | rasterizer(render_window, gpu, cpu_memory, screen_info, device, memory_allocator, | 100 | rasterizer(render_window, gpu, cpu_memory, screen_info, device, memory_allocator, |
diff --git a/src/video_core/renderer_vulkan/vk_present_manager.cpp b/src/video_core/renderer_vulkan/vk_present_manager.cpp index c49583013..77832720d 100644 --- a/src/video_core/renderer_vulkan/vk_present_manager.cpp +++ b/src/video_core/renderer_vulkan/vk_present_manager.cpp | |||
| @@ -4,10 +4,12 @@ | |||
| 4 | #include "common/microprofile.h" | 4 | #include "common/microprofile.h" |
| 5 | #include "common/settings.h" | 5 | #include "common/settings.h" |
| 6 | #include "common/thread.h" | 6 | #include "common/thread.h" |
| 7 | #include "core/frontend/emu_window.h" | ||
| 7 | #include "video_core/renderer_vulkan/vk_present_manager.h" | 8 | #include "video_core/renderer_vulkan/vk_present_manager.h" |
| 8 | #include "video_core/renderer_vulkan/vk_scheduler.h" | 9 | #include "video_core/renderer_vulkan/vk_scheduler.h" |
| 9 | #include "video_core/renderer_vulkan/vk_swapchain.h" | 10 | #include "video_core/renderer_vulkan/vk_swapchain.h" |
| 10 | #include "video_core/vulkan_common/vulkan_device.h" | 11 | #include "video_core/vulkan_common/vulkan_device.h" |
| 12 | #include "video_core/vulkan_common/vulkan_surface.h" | ||
| 11 | 13 | ||
| 12 | namespace Vulkan { | 14 | namespace Vulkan { |
| 13 | 15 | ||
| @@ -92,14 +94,17 @@ bool CanBlitToSwapchain(const vk::PhysicalDevice& physical_device, VkFormat form | |||
| 92 | 94 | ||
| 93 | } // Anonymous namespace | 95 | } // Anonymous namespace |
| 94 | 96 | ||
| 95 | PresentManager::PresentManager(Core::Frontend::EmuWindow& render_window_, const Device& device_, | 97 | PresentManager::PresentManager(const vk::Instance& instance_, |
| 98 | Core::Frontend::EmuWindow& render_window_, const Device& device_, | ||
| 96 | MemoryAllocator& memory_allocator_, Scheduler& scheduler_, | 99 | MemoryAllocator& memory_allocator_, Scheduler& scheduler_, |
| 97 | Swapchain& swapchain_) | 100 | Swapchain& swapchain_, vk::SurfaceKHR& surface_) |
| 98 | : render_window{render_window_}, device{device_}, | 101 | : instance{instance_}, render_window{render_window_}, device{device_}, |
| 99 | memory_allocator{memory_allocator_}, scheduler{scheduler_}, swapchain{swapchain_}, | 102 | memory_allocator{memory_allocator_}, scheduler{scheduler_}, swapchain{swapchain_}, |
| 100 | blit_supported{CanBlitToSwapchain(device.GetPhysical(), swapchain.GetImageViewFormat())}, | 103 | surface{surface_}, blit_supported{CanBlitToSwapchain(device.GetPhysical(), |
| 104 | swapchain.GetImageViewFormat())}, | ||
| 101 | use_present_thread{Settings::values.async_presentation.GetValue()}, | 105 | use_present_thread{Settings::values.async_presentation.GetValue()}, |
| 102 | image_count{swapchain.GetImageCount()} { | 106 | image_count{swapchain.GetImageCount()}, last_render_surface{ |
| 107 | render_window_.GetWindowInfo().render_surface} { | ||
| 103 | 108 | ||
| 104 | auto& dld = device.GetLogical(); | 109 | auto& dld = device.GetLogical(); |
| 105 | cmdpool = dld.CreateCommandPool({ | 110 | cmdpool = dld.CreateCommandPool({ |
| @@ -290,10 +295,19 @@ void PresentManager::CopyToSwapchain(Frame* frame) { | |||
| 290 | MICROPROFILE_SCOPE(Vulkan_CopyToSwapchain); | 295 | MICROPROFILE_SCOPE(Vulkan_CopyToSwapchain); |
| 291 | 296 | ||
| 292 | const auto recreate_swapchain = [&] { | 297 | const auto recreate_swapchain = [&] { |
| 293 | swapchain.Create(frame->width, frame->height, frame->is_srgb); | 298 | swapchain.Create(*surface, frame->width, frame->height, frame->is_srgb); |
| 294 | image_count = swapchain.GetImageCount(); | 299 | image_count = swapchain.GetImageCount(); |
| 295 | }; | 300 | }; |
| 296 | 301 | ||
| 302 | #ifdef ANDROID | ||
| 303 | // If the frontend recreated the surface, recreate the renderer surface and swapchain. | ||
| 304 | if (last_render_surface != render_window.GetWindowInfo().render_surface) { | ||
| 305 | last_render_surface = render_window.GetWindowInfo().render_surface; | ||
| 306 | surface = CreateSurface(instance, render_window.GetWindowInfo()); | ||
| 307 | recreate_swapchain(); | ||
| 308 | } | ||
| 309 | #endif | ||
| 310 | |||
| 297 | // If the size or colorspace of the incoming frames has changed, recreate the swapchain | 311 | // If the size or colorspace of the incoming frames has changed, recreate the swapchain |
| 298 | // to account for that. | 312 | // to account for that. |
| 299 | const bool srgb_changed = swapchain.NeedsRecreation(frame->is_srgb); | 313 | const bool srgb_changed = swapchain.NeedsRecreation(frame->is_srgb); |
| @@ -454,4 +468,4 @@ void PresentManager::CopyToSwapchain(Frame* frame) { | |||
| 454 | swapchain.Present(render_semaphore); | 468 | swapchain.Present(render_semaphore); |
| 455 | } | 469 | } |
| 456 | 470 | ||
| 457 | } // namespace Vulkan | 471 | } // namespace Vulkan \ No newline at end of file |
diff --git a/src/video_core/renderer_vulkan/vk_present_manager.h b/src/video_core/renderer_vulkan/vk_present_manager.h index 420a775e2..3cbfce4ed 100644 --- a/src/video_core/renderer_vulkan/vk_present_manager.h +++ b/src/video_core/renderer_vulkan/vk_present_manager.h | |||
| @@ -37,8 +37,9 @@ struct Frame { | |||
| 37 | 37 | ||
| 38 | class PresentManager { | 38 | class PresentManager { |
| 39 | public: | 39 | public: |
| 40 | PresentManager(Core::Frontend::EmuWindow& render_window, const Device& device, | 40 | PresentManager(const vk::Instance& instance, Core::Frontend::EmuWindow& render_window, |
| 41 | MemoryAllocator& memory_allocator, Scheduler& scheduler, Swapchain& swapchain); | 41 | const Device& device, MemoryAllocator& memory_allocator, Scheduler& scheduler, |
| 42 | Swapchain& swapchain, vk::SurfaceKHR& surface); | ||
| 42 | ~PresentManager(); | 43 | ~PresentManager(); |
| 43 | 44 | ||
| 44 | /// Returns the last used presentation frame | 45 | /// Returns the last used presentation frame |
| @@ -60,11 +61,13 @@ private: | |||
| 60 | void CopyToSwapchain(Frame* frame); | 61 | void CopyToSwapchain(Frame* frame); |
| 61 | 62 | ||
| 62 | private: | 63 | private: |
| 64 | const vk::Instance& instance; | ||
| 63 | Core::Frontend::EmuWindow& render_window; | 65 | Core::Frontend::EmuWindow& render_window; |
| 64 | const Device& device; | 66 | const Device& device; |
| 65 | MemoryAllocator& memory_allocator; | 67 | MemoryAllocator& memory_allocator; |
| 66 | Scheduler& scheduler; | 68 | Scheduler& scheduler; |
| 67 | Swapchain& swapchain; | 69 | Swapchain& swapchain; |
| 70 | vk::SurfaceKHR& surface; | ||
| 68 | vk::CommandPool cmdpool; | 71 | vk::CommandPool cmdpool; |
| 69 | std::vector<Frame> frames; | 72 | std::vector<Frame> frames; |
| 70 | std::queue<Frame*> present_queue; | 73 | std::queue<Frame*> present_queue; |
| @@ -77,7 +80,8 @@ private: | |||
| 77 | std::jthread present_thread; | 80 | std::jthread present_thread; |
| 78 | bool blit_supported; | 81 | bool blit_supported; |
| 79 | bool use_present_thread; | 82 | bool use_present_thread; |
| 80 | std::size_t image_count; | 83 | std::size_t image_count{}; |
| 84 | void* last_render_surface{}; | ||
| 81 | }; | 85 | }; |
| 82 | 86 | ||
| 83 | } // namespace Vulkan | 87 | } // namespace Vulkan |
diff --git a/src/video_core/renderer_vulkan/vk_swapchain.cpp b/src/video_core/renderer_vulkan/vk_swapchain.cpp index e43a993f9..afcf34fba 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.cpp +++ b/src/video_core/renderer_vulkan/vk_swapchain.cpp | |||
| @@ -107,16 +107,17 @@ VkCompositeAlphaFlagBitsKHR ChooseAlphaFlags(const VkSurfaceCapabilitiesKHR& cap | |||
| 107 | Swapchain::Swapchain(VkSurfaceKHR surface_, const Device& device_, Scheduler& scheduler_, | 107 | Swapchain::Swapchain(VkSurfaceKHR surface_, const Device& device_, Scheduler& scheduler_, |
| 108 | u32 width_, u32 height_, bool srgb) | 108 | u32 width_, u32 height_, bool srgb) |
| 109 | : surface{surface_}, device{device_}, scheduler{scheduler_} { | 109 | : surface{surface_}, device{device_}, scheduler{scheduler_} { |
| 110 | Create(width_, height_, srgb); | 110 | Create(surface_, width_, height_, srgb); |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | Swapchain::~Swapchain() = default; | 113 | Swapchain::~Swapchain() = default; |
| 114 | 114 | ||
| 115 | void Swapchain::Create(u32 width_, u32 height_, bool srgb) { | 115 | void Swapchain::Create(VkSurfaceKHR surface_, u32 width_, u32 height_, bool srgb) { |
| 116 | is_outdated = false; | 116 | is_outdated = false; |
| 117 | is_suboptimal = false; | 117 | is_suboptimal = false; |
| 118 | width = width_; | 118 | width = width_; |
| 119 | height = height_; | 119 | height = height_; |
| 120 | surface = surface_; | ||
| 120 | 121 | ||
| 121 | const auto physical_device = device.GetPhysical(); | 122 | const auto physical_device = device.GetPhysical(); |
| 122 | const auto capabilities{physical_device.GetSurfaceCapabilitiesKHR(surface)}; | 123 | const auto capabilities{physical_device.GetSurfaceCapabilitiesKHR(surface)}; |
diff --git a/src/video_core/renderer_vulkan/vk_swapchain.h b/src/video_core/renderer_vulkan/vk_swapchain.h index bf1ea7254..b8a1465a6 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.h +++ b/src/video_core/renderer_vulkan/vk_swapchain.h | |||
| @@ -24,7 +24,7 @@ public: | |||
| 24 | ~Swapchain(); | 24 | ~Swapchain(); |
| 25 | 25 | ||
| 26 | /// Creates (or recreates) the swapchain with a given size. | 26 | /// Creates (or recreates) the swapchain with a given size. |
| 27 | void Create(u32 width, u32 height, bool srgb); | 27 | void Create(VkSurfaceKHR surface, u32 width, u32 height, bool srgb); |
| 28 | 28 | ||
| 29 | /// Acquires the next image in the swapchain, waits as needed. | 29 | /// Acquires the next image in the swapchain, waits as needed. |
| 30 | bool AcquireNextImage(); | 30 | bool AcquireNextImage(); |
| @@ -118,7 +118,7 @@ private: | |||
| 118 | 118 | ||
| 119 | bool NeedsPresentModeUpdate() const; | 119 | bool NeedsPresentModeUpdate() const; |
| 120 | 120 | ||
| 121 | const VkSurfaceKHR surface; | 121 | VkSurfaceKHR surface; |
| 122 | const Device& device; | 122 | const Device& device; |
| 123 | Scheduler& scheduler; | 123 | Scheduler& scheduler; |
| 124 | 124 | ||