comparison semiconginev2/rendering/swapchain.nim @ 1239:69489a678141

add: better syncing, better swapchain access, correct font offset, two font-rendering tests
author sam <sam@basx.dev>
date Mon, 22 Jul 2024 00:46:10 +0700
parents 5dcb503ef0c0
children
comparison
equal deleted inserted replaced
1238:03634915bbdb 1239:69489a678141
1 const N_FRAMEBUFFERS = 3'u32 1 const N_FRAMEBUFFERS = 3'u32
2 2
3 proc InitSwapchain*( 3 proc InitSwapchain(
4 renderPass: RenderPass, 4 renderPass: RenderPass,
5 vSync: bool = false, 5 vSync: bool = false,
6 oldSwapchain: Swapchain = nil, 6 oldSwapchain: Swapchain = nil,
7 ): Option[Swapchain] = 7 ): Swapchain =
8 assert vulkan.instance.Valid, "Vulkan not initialized" 8 assert vulkan.instance.Valid, "Vulkan not initialized"
9 9
10 var capabilities: VkSurfaceCapabilitiesKHR 10 var capabilities: VkSurfaceCapabilitiesKHR
11 checkVkResult vkGetPhysicalDeviceSurfaceCapabilitiesKHR(vulkan.physicalDevice, vulkan.surface, addr(capabilities)) 11 checkVkResult vkGetPhysicalDeviceSurfaceCapabilitiesKHR(vulkan.physicalDevice, vulkan.surface, addr(capabilities))
12 let 12 let
13 width = capabilities.currentExtent.width 13 width = capabilities.currentExtent.width
14 height = capabilities.currentExtent.height 14 height = capabilities.currentExtent.height
15 15
16 if width == 0 or height == 0: 16 if width == 0 or height == 0:
17 return none(Swapchain) 17 return nil
18 18
19 # following "count" is established according to vulkan specs 19 # following "count" is established according to vulkan specs
20 var minFramebufferCount = N_FRAMEBUFFERS 20 var minFramebufferCount = N_FRAMEBUFFERS
21 minFramebufferCount = max(minFramebufferCount, capabilities.minImageCount) 21 minFramebufferCount = max(minFramebufferCount, capabilities.minImageCount)
22 if capabilities.maxImageCount != 0: 22 if capabilities.maxImageCount != 0:
47 vSync: vSync, 47 vSync: vSync,
48 oldSwapchain: oldSwapchain, 48 oldSwapchain: oldSwapchain,
49 ) 49 )
50 50
51 if vkCreateSwapchainKHR(vulkan.device, addr(swapchainCreateInfo), nil, addr(swapchain.vk)) != VK_SUCCESS: 51 if vkCreateSwapchainKHR(vulkan.device, addr(swapchainCreateInfo), nil, addr(swapchain.vk)) != VK_SUCCESS:
52 return none(Swapchain) 52 return nil
53 53
54 if swapchain.oldSwapchain != nil: 54 if swapchain.oldSwapchain != nil:
55 swapchain.oldSwapchainCounter = INFLIGHTFRAMES.int * 2 55 swapchain.oldSwapchainCounter = INFLIGHTFRAMES.int * 2
56 56
57 # create depth buffer image+view if desired 57 # create depth buffer image+view if desired
148 level: VK_COMMAND_BUFFER_LEVEL_PRIMARY, 148 level: VK_COMMAND_BUFFER_LEVEL_PRIMARY,
149 commandBufferCount: INFLIGHTFRAMES, 149 commandBufferCount: INFLIGHTFRAMES,
150 ) 150 )
151 checkVkResult vkAllocateCommandBuffers(vulkan.device, addr(allocInfo), swapchain.commandBuffers.ToCPointer) 151 checkVkResult vkAllocateCommandBuffers(vulkan.device, addr(allocInfo), swapchain.commandBuffers.ToCPointer)
152 152
153 return some(swapchain) 153 return swapchain
154 154
155 proc DestroySwapchain*(swapchain: Swapchain) = 155 proc DestroySwapchain*(swapchain: Swapchain) =
156 if swapchain.oldSwapchain != nil:
157 DestroySwapchain(swapchain.oldSwapchain)
156 158
157 if swapchain.msaaImage.Valid: 159 if swapchain.msaaImage.Valid:
158 vkDestroyImageView(vulkan.device, swapchain.msaaImageView, nil) 160 vkDestroyImageView(vulkan.device, swapchain.msaaImageView, nil)
159 vkDestroyImage(vulkan.device, swapchain.msaaImage, nil) 161 vkDestroyImage(vulkan.device, swapchain.msaaImage, nil)
160 vkFreeMemory(vulkan.device, swapchain.msaaMemory, nil) 162 vkFreeMemory(vulkan.device, swapchain.msaaMemory, nil)
243 return false 245 return false
244 246
245 swapchain.currentFiF = (uint32(swapchain.currentFiF) + 1) mod INFLIGHTFRAMES 247 swapchain.currentFiF = (uint32(swapchain.currentFiF) + 1) mod INFLIGHTFRAMES
246 return true 248 return true
247 249
248 proc Recreate(swapchain: Swapchain): Option[Swapchain] = 250 proc Recreate(swapchain: Swapchain): Swapchain =
249 InitSwapchain( 251 InitSwapchain(
250 renderPass = swapchain.renderPass, 252 renderPass = swapchain.renderPass,
251 vSync = swapchain.vSync, 253 vSync = swapchain.vSync,
252 oldSwapchain = swapchain, 254 oldSwapchain = swapchain,
253 ) 255 )
254 256
255 template WithNextFrame*(theSwapchain: var Swapchain, framebufferName, commandBufferName, body: untyped): untyped = 257 template WithNextFrame*(framebufferName, commandBufferName, body: untyped): untyped =
256 var maybeFramebuffer = TryAcquireNextImage(theSwapchain) 258 assert vulkan.swapchain != nil, "Swapchain has not been initialized yet"
259 var maybeFramebuffer = TryAcquireNextImage(vulkan.swapchain)
257 if maybeFramebuffer.isSome: 260 if maybeFramebuffer.isSome:
258 block: 261 block:
259 let `framebufferName` {.inject.} = maybeFramebuffer.get 262 let `framebufferName` {.inject.} = maybeFramebuffer.get
260 let `commandBufferName` {.inject.} = theSwapchain.commandBuffers[theSwapchain.currentFiF] 263 let `commandBufferName` {.inject.} = vulkan.swapchain.commandBuffers[vulkan.swapchain.currentFiF]
261 let beginInfo = VkCommandBufferBeginInfo( 264 let beginInfo = VkCommandBufferBeginInfo(
262 sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, 265 sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
263 flags: VkCommandBufferUsageFlags(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT), 266 flags: VkCommandBufferUsageFlags(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT),
264 ) 267 )
265 checkVkResult vkResetCommandBuffer(`commandBufferName`, VkCommandBufferResetFlags(0)) 268 checkVkResult vkResetCommandBuffer(`commandBufferName`, VkCommandBufferResetFlags(0))
266 checkVkResult vkBeginCommandBuffer(`commandBufferName`, addr(beginInfo)) 269 checkVkResult vkBeginCommandBuffer(`commandBufferName`, addr(beginInfo))
267 270
268 body 271 body
269 272
270 checkVkResult vkEndCommandBuffer(`commandBufferName`) 273 checkVkResult vkEndCommandBuffer(`commandBufferName`)
271 discard Swap(swapchain = theSwapchain, commandBuffer = `commandBufferName`) 274 discard Swap(swapchain = vulkan.swapchain, commandBuffer = `commandBufferName`)
272 else: 275 else:
273 let maybeNewSwapchain = Recreate(theSwapchain) 276 let newSwapchain = Recreate(vulkan.swapchain)
274 if maybeNewSwapchain.isSome: 277 if newSwapchain != nil:
275 theSwapchain = maybeNewSwapchain.get 278 vulkan.swapchain = newSwapchain
276