Mercurial > games > semicongine
diff semiconginev2/rendering/swapchain.nim @ 1229:5dcb503ef0c0
did: refactor renderpass a bit, enable depth buffering and msaa on offscreen-rendering
author | sam <sam@basx.dev> |
---|---|
date | Thu, 18 Jul 2024 21:32:41 +0700 |
parents | 56781cc0fc7c |
children | 69489a678141 |
line wrap: on
line diff
--- a/semiconginev2/rendering/swapchain.nim Thu Jul 18 16:33:24 2024 +0700 +++ b/semiconginev2/rendering/swapchain.nim Thu Jul 18 21:32:41 2024 +0700 @@ -1,17 +1,15 @@ const N_FRAMEBUFFERS = 3'u32 proc InitSwapchain*( - renderPass: VkRenderPass, + renderPass: RenderPass, vSync: bool = false, - samples = VK_SAMPLE_COUNT_1_BIT, - oldSwapchain: ref Swapchain = nil, + oldSwapchain: Swapchain = nil, ): Option[Swapchain] = assert vulkan.instance.Valid, "Vulkan not initialized" var capabilities: VkSurfaceCapabilitiesKHR checkVkResult vkGetPhysicalDeviceSurfaceCapabilitiesKHR(vulkan.physicalDevice, vulkan.surface, addr(capabilities)) let - format = DefaultSurfaceFormat() width = capabilities.currentExtent.width height = capabilities.currentExtent.height @@ -30,7 +28,7 @@ sType: VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, surface: vulkan.surface, minImageCount: minFramebufferCount, - imageFormat: format, + imageFormat: SURFACE_FORMAT, imageColorSpace: VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, # only one supported without special extensions imageExtent: capabilities.currentExtent, imageArrayLayers: 1, @@ -42,27 +40,54 @@ clipped: true, oldSwapchain: if oldSwapchain != nil: oldSwapchain.vk else: VkSwapchainKHR(0), ) - var swapchain: Swapchain + var swapchain = Swapchain( + width: width, + height: height, + renderPass: renderPass, + vSync: vSync, + oldSwapchain: oldSwapchain, + ) + if vkCreateSwapchainKHR(vulkan.device, addr(swapchainCreateInfo), nil, addr(swapchain.vk)) != VK_SUCCESS: return none(Swapchain) - swapchain.width = width - swapchain.height = height - swapchain.renderPass = renderPass - swapchain.vSync = vSync - swapchain.samples = samples - swapchain.oldSwapchain = oldSwapchain if swapchain.oldSwapchain != nil: swapchain.oldSwapchainCounter = INFLIGHTFRAMES.int * 2 + # create depth buffer image+view if desired + if renderPass.depthBuffer: + swapchain.depthImage = svkCreate2DImage( + width = width, + height = height, + format = DEPTH_FORMAT, + usage = [VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT], + samples = renderPass.samples, + ) + let requirements = svkGetImageMemoryRequirements(swapchain.depthImage) + swapchain.depthMemory = svkAllocateMemory( + requirements.size, + BestMemory(mappable = false, filter = requirements.memoryTypes) + ) + checkVkResult vkBindImageMemory( + vulkan.device, + swapchain.depthImage, + swapchain.depthMemory, + 0, + ) + swapchain.depthImageView = svkCreate2DImageView( + image = swapchain.depthImage, + format = DEPTH_FORMAT, + aspect = VK_IMAGE_ASPECT_DEPTH_BIT + ) + # create msaa image+view if desired - if samples != VK_SAMPLE_COUNT_1_BIT: + if renderPass.samples != VK_SAMPLE_COUNT_1_BIT: swapchain.msaaImage = svkCreate2DImage( width = width, height = height, - format = format, + format = SURFACE_FORMAT, usage = [VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT], - samples = samples, + samples = renderPass.samples, ) let requirements = svkGetImageMemoryRequirements(swapchain.msaaImage) swapchain.msaaMemory = svkAllocateMemory( @@ -75,7 +100,7 @@ swapchain.msaaMemory, 0, ) - swapchain.msaaImageView = svkCreate2DImageView(swapchain.msaaImage, format) + swapchain.msaaImageView = svkCreate2DImageView(image = swapchain.msaaImage, format = SURFACE_FORMAT) # create framebuffers var actualNFramebuffers: uint32 @@ -84,11 +109,25 @@ checkVkResult vkGetSwapchainImagesKHR(vulkan.device, swapchain.vk, addr(actualNFramebuffers), framebuffers.ToCPointer) for framebuffer in framebuffers: - swapchain.framebufferViews.add svkCreate2DImageView(framebuffer, format) - if samples == VK_SAMPLE_COUNT_1_BIT: - swapchain.framebuffers.add svkCreateFramebuffer(renderPass, width, height, [swapchain.framebufferViews[^1]]) + swapchain.framebufferViews.add svkCreate2DImageView(framebuffer, SURFACE_FORMAT) + var attachments: seq[VkImageView] + if renderPass.samples == VK_SAMPLE_COUNT_1_BIT: + if renderPass.depthBuffer: + attachments = @[swapchain.framebufferViews[^1], swapchain.depthImageView] + else: + attachments = @[swapchain.framebufferViews[^1]] else: - swapchain.framebuffers.add svkCreateFramebuffer(renderPass, width, height, [swapchain.msaaImageView, swapchain.framebufferViews[^1]]) + if renderPass.depthBuffer: + attachments = @[swapchain.msaaImageView, swapchain.depthImageView, swapchain.framebufferViews[^1]] + else: + attachments = @[swapchain.msaaImageView, swapchain.framebufferViews[^1]] + + swapchain.framebuffers.add svkCreateFramebuffer( + renderpass = renderPass.vk, + width = width, + height = height, + attachments = attachments, + ) # create sync primitives for i in 0 ..< INFLIGHTFRAMES: @@ -115,11 +154,16 @@ proc DestroySwapchain*(swapchain: Swapchain) = - if swapchain.samples != VK_SAMPLE_COUNT_1_BIT: + if swapchain.msaaImage.Valid: vkDestroyImageView(vulkan.device, swapchain.msaaImageView, nil) vkDestroyImage(vulkan.device, swapchain.msaaImage, nil) vkFreeMemory(vulkan.device, swapchain.msaaMemory, nil) + if swapchain.depthImage.Valid: + vkDestroyImageView(vulkan.device, swapchain.depthImageView, nil) + vkDestroyImage(vulkan.device, swapchain.depthImage, nil) + vkFreeMemory(vulkan.device, swapchain.depthMemory, nil) + for fence in swapchain.queueFinishedFence: vkDestroyFence(vulkan.device, fence, nil) @@ -139,7 +183,7 @@ vkDestroySwapchainKHR(vulkan.device, swapchain.vk, nil) -proc TryAcquireNextImage(swapchain: var Swapchain): Option[VkFramebuffer] = +proc TryAcquireNextImage(swapchain: Swapchain): Option[VkFramebuffer] = if not swapchain.queueFinishedFence[swapchain.currentFiF].Await(100_000_000): return none(VkFramebuffer) @@ -158,7 +202,7 @@ return none(VkFramebuffer) return some(swapchain.framebuffers[swapchain.currentFramebufferIndex]) -proc Swap(swapchain: var Swapchain, commandBuffer: VkCommandBuffer): bool = +proc Swap(swapchain: Swapchain, commandBuffer: VkCommandBuffer): bool = var waitStage = VkPipelineStageFlags(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT) submitInfo = VkSubmitInfo( @@ -192,7 +236,7 @@ if swapchain.oldSwapchain != nil: dec swapchain.oldSwapchainCounter if swapchain.oldSwapchainCounter <= 0: - DestroySwapchain(swapchain.oldSwapchain[]) + DestroySwapchain(swapchain.oldSwapchain) swapchain.oldSwapchain = nil if presentResult != VK_SUCCESS: @@ -202,21 +246,18 @@ return true proc Recreate(swapchain: Swapchain): Option[Swapchain] = - var oldSwapchain = new Swapchain - oldSwapchain[] = swapchain InitSwapchain( renderPass = swapchain.renderPass, vSync = swapchain.vSync, - samples = swapchain.samples, - oldSwapchain = oldSwapchain, + oldSwapchain = swapchain, ) -template WithNextFrame*(swapchain: var Swapchain, framebufferName, commandBufferName, body: untyped): untyped = - var maybeFramebuffer = TryAcquireNextImage(swapchain) +template WithNextFrame*(theSwapchain: var Swapchain, framebufferName, commandBufferName, body: untyped): untyped = + var maybeFramebuffer = TryAcquireNextImage(theSwapchain) if maybeFramebuffer.isSome: block: let `framebufferName` {.inject.} = maybeFramebuffer.get - let `commandBufferName` {.inject.} = swapchain.commandBuffers[swapchain.currentFiF] + let `commandBufferName` {.inject.} = theSwapchain.commandBuffers[theSwapchain.currentFiF] let beginInfo = VkCommandBufferBeginInfo( sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, flags: VkCommandBufferUsageFlags(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT), @@ -227,9 +268,9 @@ body checkVkResult vkEndCommandBuffer(`commandBufferName`) - discard Swap(swapchain = swapchain, commandBuffer = `commandBufferName`) + discard Swap(swapchain = theSwapchain, commandBuffer = `commandBufferName`) else: - let maybeNewSwapchain = Recreate(swapchain) + let maybeNewSwapchain = Recreate(theSwapchain) if maybeNewSwapchain.isSome: - swapchain = maybeNewSwapchain.get + theSwapchain = maybeNewSwapchain.get