mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Vulkan: Smoothly recreate the swapchain using oldSwapchain on "resize" on Windows
This commit is contained in:
1 parent
84aeec7148
commit
6338832015
5 files changed
+27
-6
No files matched your search
@@ -397,6 +397,8 @@ void VulkanContext::DestroySurface() {
|
||||
if (surface_ != VK_NULL_HANDLE) {
|
||||
vkDestroySurfaceKHR(instance_, surface_, nullptr);
|
||||
surface_ = VK_NULL_HANDLE;
|
||||
|
||||
// NOTE: We do not reset winSysData1 and 2, it's useful for debugging to compare them.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -935,6 +937,12 @@ void VulkanContext::SetDebugNameImpl(uint64_t handle, VkObjectType type, const c
|
||||
|
||||
VkResult VulkanContext::InitSurface(WindowSystem winsys, void *data1, void *data2) {
|
||||
winsys_ = winsys;
|
||||
if (winsysData1_ != data1) {
|
||||
WARN_LOG(Log::G3D, "winsysData1 changed from %p to %p", winsysData1_, data1);
|
||||
}
|
||||
if (winsysData2_ != data2) {
|
||||
WARN_LOG(Log::G3D, "winsysData2 changed from %p to %p", winsysData2_, data2);
|
||||
}
|
||||
winsysData1_ = data1;
|
||||
winsysData2_ = data2;
|
||||
return ReinitSurface();
|
||||
@@ -1344,6 +1352,10 @@ bool VulkanContext::InitSwapchain() {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (swapchain_) {
|
||||
INFO_LOG(Log::G3D, "Swapchain already exists, recreating...");
|
||||
}
|
||||
|
||||
VkResult res = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_devices_[physical_device_], surface_, &surfCapabilities_);
|
||||
if (res == VK_ERROR_SURFACE_LOST_KHR) {
|
||||
// Not much to do.
|
||||
@@ -1496,6 +1508,8 @@ bool VulkanContext::InitSwapchain() {
|
||||
}
|
||||
}
|
||||
|
||||
VkSwapchainKHR oldSwapchain = swapchain_;
|
||||
|
||||
VkSwapchainCreateInfoKHR swap_chain_info{ VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR };
|
||||
swap_chain_info.surface = surface_;
|
||||
swap_chain_info.minImageCount = desiredNumberOfSwapChainImages;
|
||||
@@ -1506,7 +1520,7 @@ bool VulkanContext::InitSwapchain() {
|
||||
swap_chain_info.preTransform = preTransform;
|
||||
swap_chain_info.imageArrayLayers = 1;
|
||||
swap_chain_info.presentMode = swapchainPresentMode;
|
||||
swap_chain_info.oldSwapchain = VK_NULL_HANDLE;
|
||||
swap_chain_info.oldSwapchain = swapchain_;
|
||||
swap_chain_info.clipped = true;
|
||||
swap_chain_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
|
||||
@@ -1535,6 +1549,11 @@ bool VulkanContext::InitSwapchain() {
|
||||
}
|
||||
INFO_LOG(Log::G3D, "Created swapchain: %dx%d %s", swap_chain_info.imageExtent.width, swap_chain_info.imageExtent.height, (surfCapabilities_.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) ? "(TRANSFER_SRC_BIT supported)" : "");
|
||||
swapchainInited_ = true;
|
||||
|
||||
if (oldSwapchain != VK_NULL_HANDLE) {
|
||||
vkDestroySwapchainKHR(device_, oldSwapchain, nullptr);
|
||||
INFO_LOG(Log::G3D, "Destroyed old swapchain.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@ template<class R, class T> inline void ChainStruct(R &root, T *newStruct) {
|
||||
|
||||
// Not all will be usable on all platforms, of course...
|
||||
enum WindowSystem {
|
||||
WINDOWSYSTEM_UNINITIALIZED,
|
||||
#ifdef _WIN32
|
||||
WINDOWSYSTEM_WIN32,
|
||||
#endif
|
||||
@@ -450,7 +451,7 @@ private:
|
||||
|
||||
bool CheckLayers(const std::vector<LayerProperties> &layer_props, const std::vector<const char *> &layer_names) const;
|
||||
|
||||
WindowSystem winsys_{};
|
||||
WindowSystem winsys_ = WINDOWSYSTEM_UNINITIALIZED;
|
||||
|
||||
// Don't use the real types here to avoid having to include platform-specific stuff
|
||||
// that we really don't want in everything that uses VulkanContext.
|
||||
|
||||
@@ -174,7 +174,6 @@ bool VulkanQueueRunner::InitDepthStencilBuffer(VkCommandBuffer cmd, VulkanBarrie
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void VulkanQueueRunner::DestroyBackBuffers() {
|
||||
if (depth_.view) {
|
||||
vulkan_->Delete().QueueDeleteImageView(depth_.view);
|
||||
|
||||
@@ -164,7 +164,6 @@ void WindowsVulkanContext::Shutdown() {
|
||||
|
||||
void WindowsVulkanContext::Resize() {
|
||||
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight());
|
||||
vulkan_->DestroySwapchain();
|
||||
VulkanContext::CreateInfo info{};
|
||||
InitVulkanCreateInfoFromConfig(&info);
|
||||
vulkan_->InitSwapchain();
|
||||
|
||||
@@ -120,13 +120,16 @@ void AndroidVulkanContext::Shutdown() {
|
||||
|
||||
void AndroidVulkanContext::Resize() {
|
||||
INFO_LOG(Log::G3D, "AndroidVulkanContext::Resize begin (oldsize: %dx%d)", g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
|
||||
VulkanContext::CreateInfo info{};
|
||||
InitVulkanCreateInfoFromConfig(&info);
|
||||
|
||||
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
|
||||
g_Vulkan->DestroySwapchain();
|
||||
|
||||
// TODO: We should only destroy the surface here if the window changed. We can track this inside g_Vulkan.
|
||||
|
||||
g_Vulkan->DestroySurface();
|
||||
|
||||
VulkanContext::CreateInfo info{};
|
||||
InitVulkanCreateInfoFromConfig(&info);
|
||||
g_Vulkan->UpdateCreateInfo(info);
|
||||
|
||||
g_Vulkan->ReinitSurface();
|
||||
|
||||
Reference in new issue
Block a user