changeset 132:25fe4972ef9c

add: support for smooth swapchain-recreation
author Sam <sam@basx.dev>
date Thu, 20 Apr 2023 01:00:48 +0700
parents 11666d28e04d
children 9f2c178beb60
files src/semicongine/config.nim src/semicongine/renderer.nim src/semicongine/vulkan/swapchain.nim
diffstat 3 files changed, 14 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/semicongine/config.nim	Wed Apr 19 01:45:16 2023 +0700
+++ b/src/semicongine/config.nim	Thu Apr 20 01:00:48 2023 +0700
@@ -7,7 +7,6 @@
 import std/os
 
 
-
 # build configuration
 # =====================
 
@@ -34,6 +33,7 @@
   var configUpdates: Channel[(string, Config)]
   configUpdates.open()
 
+
 # runtime configuration
 # =====================
 # namespace is the path from the CONFIGROOT to the according config file without the file extension
--- a/src/semicongine/renderer.nim	Wed Apr 19 01:45:16 2023 +0700
+++ b/src/semicongine/renderer.nim	Thu Apr 20 01:00:48 2023 +0700
@@ -12,6 +12,7 @@
 import ./vulkan/physicaldevice
 import ./vulkan/renderpass
 import ./vulkan/swapchain
+import ./vulkan/syncing
 
 import ./entity
 import ./mesh
@@ -131,8 +132,10 @@
   var
     commandBufferResult = renderer.swapchain.nextFrame()
     commandBuffer: VkCommandBuffer
+    oldSwapchain: Swapchain
 
   if not commandBufferResult.isSome:
+    oldSwapchain = renderer.swapchain
     let res = renderer.swapchain.recreate()
     if res.isSome:
       renderer.swapchain = res.get()
@@ -166,12 +169,17 @@
   commandBuffer.endRenderCommands()
 
   if not renderer.swapchain.swap():
+    oldSwapchain = renderer.swapchain
     let res = renderer.swapchain.recreate()
     if res.isSome:
       renderer.swapchain = res.get()
     else:
       raise newException(Exception, "Unable to recreate swapchain")
 
+  if oldSwapchain.vk.valid:
+    oldSwapchain.queueFinishedFence[oldSwapchain.currentInFlight].wait()
+    oldSwapchain.destroy()
+
 
 func framesRendered*(renderer: Renderer): uint64 =
   renderer.swapchain.framesRendered
--- a/src/semicongine/vulkan/swapchain.nim	Wed Apr 19 01:45:16 2023 +0700
+++ b/src/semicongine/vulkan/swapchain.nim	Thu Apr 20 01:00:48 2023 +0700
@@ -25,7 +25,7 @@
     currentInFlight*: int
     currentFramebufferIndex: uint32
     framesRendered*: uint64
-    queueFinishedFence: seq[Fence]
+    queueFinishedFence*: seq[Fence]
     imageAvailableSemaphore*: seq[Semaphore]
     renderFinishedSemaphore*: seq[Semaphore]
     commandBufferPool: CommandBufferPool
@@ -45,7 +45,8 @@
   queueFamily: QueueFamily,
   desiredNumberOfImages=3'u32,
   presentMode: VkPresentModeKHR=VK_PRESENT_MODE_MAILBOX_KHR,
-  inFlightFrames=2
+  inFlightFrames=2,
+  oldSwapchain=VkSwapchainKHR(0)
 ): Option[Swapchain] =
   assert device.vk.valid
   assert device.physicalDevice.vk.valid
@@ -80,6 +81,7 @@
     compositeAlpha: VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, # only used for blending with other windows, can be opaque
     presentMode: presentMode,
     clipped: true,
+    oldSwapchain: oldSwapchain,
   )
   var
     swapchain = Swapchain(
@@ -207,7 +209,6 @@
 proc recreate*(swapchain: var Swapchain): Option[Swapchain] =
   assert swapchain.vk.valid
   assert swapchain.device.vk.valid
-  checkVkResult swapchain.device.vk.vkDeviceWaitIdle()
   result = createSwapchain(
     device=swapchain.device,
     renderPass=swapchain.renderPass,
@@ -216,5 +217,5 @@
     desiredNumberOfImages=swapchain.imageCount,
     presentMode=swapchain.presentMode,
     inFlightFrames=swapchain.inFlightFrames,
+    oldSwapchain=swapchain.vk,
   )
-  swapchain.destroy()