summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_vulkan
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/renderer_vulkan')
-rw-r--r--src/video_core/renderer_vulkan/renderer_vulkan.cpp3
-rw-r--r--src/video_core/renderer_vulkan/vk_present_manager.cpp28
-rw-r--r--src/video_core/renderer_vulkan/vk_present_manager.h10
-rw-r--r--src/video_core/renderer_vulkan/vk_swapchain.cpp5
-rw-r--r--src/video_core/renderer_vulkan/vk_swapchain.h4
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_,
state_tracker(), scheduler(device, state_tracker),
swapchain(*surface, device, scheduler, render_window.GetFramebufferLayout().width,
render_window.GetFramebufferLayout().height, false),
- present_manager(render_window, device, memory_allocator, scheduler, swapchain),
+ present_manager(instance, render_window, device, memory_allocator, scheduler, swapchain,
+ surface),
blit_screen(cpu_memory, render_window, device, memory_allocator, swapchain, present_manager,
scheduler, screen_info),
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 @@
#include "common/microprofile.h"
#include "common/settings.h"
#include "common/thread.h"
+#include "core/frontend/emu_window.h"
#include "video_core/renderer_vulkan/vk_present_manager.h"
#include "video_core/renderer_vulkan/vk_scheduler.h"
#include "video_core/renderer_vulkan/vk_swapchain.h"
#include "video_core/vulkan_common/vulkan_device.h"
+#include "video_core/vulkan_common/vulkan_surface.h"
namespace Vulkan {
@@ -92,14 +94,17 @@ bool CanBlitToSwapchain(const vk::PhysicalDevice& physical_device, VkFormat form
} // Anonymous namespace
-PresentManager::PresentManager(Core::Frontend::EmuWindow& render_window_, const Device& device_,
+PresentManager::PresentManager(const vk::Instance& instance_,
+ Core::Frontend::EmuWindow& render_window_, const Device& device_,
MemoryAllocator& memory_allocator_, Scheduler& scheduler_,
- Swapchain& swapchain_)
- : render_window{render_window_}, device{device_},
+ Swapchain& swapchain_, vk::SurfaceKHR& surface_)
+ : instance{instance_}, render_window{render_window_}, device{device_},
memory_allocator{memory_allocator_}, scheduler{scheduler_}, swapchain{swapchain_},
- blit_supported{CanBlitToSwapchain(device.GetPhysical(), swapchain.GetImageViewFormat())},
+ surface{surface_}, blit_supported{CanBlitToSwapchain(device.GetPhysical(),
+ swapchain.GetImageViewFormat())},
use_present_thread{Settings::values.async_presentation.GetValue()},
- image_count{swapchain.GetImageCount()} {
+ image_count{swapchain.GetImageCount()}, last_render_surface{
+ render_window_.GetWindowInfo().render_surface} {
auto& dld = device.GetLogical();
cmdpool = dld.CreateCommandPool({
@@ -290,10 +295,19 @@ void PresentManager::CopyToSwapchain(Frame* frame) {
MICROPROFILE_SCOPE(Vulkan_CopyToSwapchain);
const auto recreate_swapchain = [&] {
- swapchain.Create(frame->width, frame->height, frame->is_srgb);
+ swapchain.Create(*surface, frame->width, frame->height, frame->is_srgb);
image_count = swapchain.GetImageCount();
};
+#ifdef ANDROID
+ // 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
+
// If the size or colorspace of the incoming frames has changed, recreate the swapchain
// to account for that.
const bool srgb_changed = swapchain.NeedsRecreation(frame->is_srgb);
@@ -454,4 +468,4 @@ void PresentManager::CopyToSwapchain(Frame* frame) {
swapchain.Present(render_semaphore);
}
-} // namespace Vulkan
+} // 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 {
class PresentManager {
public:
- PresentManager(Core::Frontend::EmuWindow& render_window, const Device& device,
- MemoryAllocator& memory_allocator, Scheduler& scheduler, Swapchain& swapchain);
+ PresentManager(const vk::Instance& instance, Core::Frontend::EmuWindow& render_window,
+ const Device& device, MemoryAllocator& memory_allocator, Scheduler& scheduler,
+ Swapchain& swapchain, vk::SurfaceKHR& surface);
~PresentManager();
/// Returns the last used presentation frame
@@ -60,11 +61,13 @@ private:
void CopyToSwapchain(Frame* frame);
private:
+ const vk::Instance& instance;
Core::Frontend::EmuWindow& render_window;
const Device& device;
MemoryAllocator& memory_allocator;
Scheduler& scheduler;
Swapchain& swapchain;
+ vk::SurfaceKHR& surface;
vk::CommandPool cmdpool;
std::vector<Frame> frames;
std::queue<Frame*> present_queue;
@@ -77,7 +80,8 @@ private:
std::jthread present_thread;
bool blit_supported;
bool use_present_thread;
- std::size_t image_count;
+ std::size_t image_count{};
+ void* last_render_surface{};
};
} // 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
Swapchain::Swapchain(VkSurfaceKHR surface_, const Device& device_, Scheduler& scheduler_,
u32 width_, u32 height_, bool srgb)
: surface{surface_}, device{device_}, scheduler{scheduler_} {
- Create(width_, height_, srgb);
+ Create(surface_, width_, height_, srgb);
}
Swapchain::~Swapchain() = default;
-void Swapchain::Create(u32 width_, u32 height_, bool srgb) {
+void Swapchain::Create(VkSurfaceKHR surface_, u32 width_, u32 height_, bool srgb) {
is_outdated = false;
is_suboptimal = false;
width = width_;
height = height_;
+ surface = surface_;
const auto physical_device = device.GetPhysical();
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:
~Swapchain();
/// Creates (or recreates) the swapchain with a given size.
- void Create(u32 width, u32 height, bool srgb);
+ void Create(VkSurfaceKHR surface, u32 width, u32 height, bool srgb);
/// Acquires the next image in the swapchain, waits as needed.
bool AcquireNextImage();
@@ -118,7 +118,7 @@ private:
bool NeedsPresentModeUpdate() const;
- const VkSurfaceKHR surface;
+ VkSurfaceKHR surface;
const Device& device;
Scheduler& scheduler;