changeset 1194:397c681f9c0c compiletime-tests

swapchain and stuff
author sam <sam@basx.dev>
date Mon, 08 Jul 2024 20:13:11 +0700
parents 5aa1184fa5eb
children cfba2b7e00d0
files semicongine/old/vulkan/swapchain.nim semicongine/rendering.nim semicongine/rendering/renderer.nim semicongine/rendering/swapchain.nim semicongine/rendering/vulkan_wrappers.nim
diffstat 5 files changed, 102 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/semicongine/old/vulkan/swapchain.nim	Mon Jul 08 16:15:33 2024 +0700
+++ b/semicongine/old/vulkan/swapchain.nim	Mon Jul 08 20:13:11 2024 +0700
@@ -99,6 +99,7 @@
     swapchain.colorImageView = swapchain.colorImage.CreateImageView()
 
   if device.vk.vkCreateSwapchainKHR(addr createInfo, nil, addr swapchain.vk) == VK_SUCCESS:
+
     checkVkResult device.vk.vkGetSwapchainImagesKHR(swapchain.vk, addr swapchain.nFramebuffers, nil)
     var framebuffers = newSeq[VkImage](swapchain.nFramebuffers)
     checkVkResult device.vk.vkGetSwapchainImagesKHR(swapchain.vk, addr swapchain.nFramebuffers, framebuffers.ToCPointer)
--- a/semicongine/rendering.nim	Mon Jul 08 16:15:33 2024 +0700
+++ b/semicongine/rendering.nim	Mon Jul 08 20:13:11 2024 +0700
@@ -31,6 +31,9 @@
     device*: VkDevice
     physicalDevice*: VkPhysicalDevice
     surface: VkSurfaceKHR
+    swapchain: VkSwapchainKHR
+    msaaImage: VkImage
+    msaaImageView: VkImageView
     window: NativeWindow
     graphicsQueueFamily*: uint32
     graphicsQueue*: VkQueue
@@ -138,6 +141,7 @@
         {.error: "Unsupported descriptor type: " & typetraits.name(typeof(value)).}
 
 include ./rendering/vulkan_wrappers
+include ./rendering/swapchain
 include ./rendering/shaders
 include ./rendering/renderer
 
--- a/semicongine/rendering/renderer.nim	Mon Jul 08 16:15:33 2024 +0700
+++ b/semicongine/rendering/renderer.nim	Mon Jul 08 20:13:11 2024 +0700
@@ -89,10 +89,6 @@
   let flags = toEnums(physicalProperties.memoryTypes[memoryTypeIndex].propertyFlags)
   return VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT in flags
 
-proc GetSurfaceFormat(): VkFormat =
-  # EVERY windows driver and almost every linux driver should support this
-  VK_FORMAT_B8G8R8A8_SRGB
-
 proc GetLayoutFor*(pipeline: Pipeline, dType: DescriptorSetType): VkDescriptorSetLayout =
   pipeline.descriptorSetLayouts[dType]
 
@@ -200,7 +196,7 @@
     of UInt32: VK_INDEX_TYPE_UINT32
 
 proc CreatePresentationRenderPass*(samples = VK_SAMPLE_COUNT_1_BIT): VkRenderPass =
-  let format = GetSurfaceFormat()
+  let format = DefaultSurfaceFormat()
   var attachments = @[VkAttachmentDescription(
     format: format,
     samples: samples,
@@ -440,28 +436,6 @@
       pImageMemoryBarriers = addr(barrier),
     )
 
-proc createImageView(image: VkImage, format: VkFormat): VkImageView =
-  var createInfo = VkImageViewCreateInfo(
-    sType: VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
-    image: image,
-    viewType: VK_IMAGE_VIEW_TYPE_2D,
-    format: format,
-    components: VkComponentMapping(
-      r: VK_COMPONENT_SWIZZLE_IDENTITY,
-      g: VK_COMPONENT_SWIZZLE_IDENTITY,
-      b: VK_COMPONENT_SWIZZLE_IDENTITY,
-      a: VK_COMPONENT_SWIZZLE_IDENTITY,
-    ),
-    subresourceRange: VkImageSubresourceRange(
-      aspectMask: VkImageAspectFlags(VK_IMAGE_ASPECT_COLOR_BIT),
-      baseMipLevel: 0,
-      levelCount: 1,
-      baseArrayLayer: 0,
-      layerCount: 1,
-    ),
-  )
-  checkVkResult vkCreateImageView(vulkan.device, addr(createInfo), nil, addr(result))
-
 proc createSampler(
   magFilter = VK_FILTER_LINEAR,
   minFilter = VK_FILTER_LINEAR,
@@ -528,7 +502,7 @@
   renderData.memory[memoryType][selectedBlockI].offsetNextFree += memoryRequirements.size
 
   # imageview can only be created after memory is bound
-  texture.imageview = createImageView(texture.vk, format)
+  texture.imageview = svkCreate2DImageView(texture.vk, format)
 
   # data transfer and layout transition
   TransitionImageLayout(texture.vk, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/semicongine/rendering/swapchain.nim	Mon Jul 08 20:13:11 2024 +0700
@@ -0,0 +1,57 @@
+const N_FRAMEBUFFERS = 3'32
+
+proc svkCreateSwapchainKHR(vSync: bool, oldSwapchain = VkSwapchainKHR(0)): VkSwapchainKHR =
+
+  var capabilities: VkSurfaceCapabilitiesKHR
+  checkVkResult device.vk.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(vulkan.surface, addr(capabilities))
+
+  if capabilities.currentExtent.width == 0 or capabilities.currentExtent.height == 0:
+    return VkSwapchainKHR(0)
+
+  # following is according to vulkan specs
+  var minFramebufferCount = N_FRAMEBUFFERS
+  minFramebufferCount = max(minFramebufferCount, capabilities.minImageCount)
+  if capabilities.maxImageCount != 0:
+    minFramebufferCount = min(minFramebufferCount, capabilities.maxImageCount)
+
+  svkGetPhysicalDeviceSurfaceFormatsKHR()
+
+  let hasTripleBuffering = VK_PRESENT_MODE_MAILBOX_KHR in svkGetPhysicalDeviceSurfacePresentModesKHR()
+  var createInfo = VkSwapchainCreateInfoKHR(
+    sType: VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
+    surface: device.physicalDevice.surface,
+    minImageCount: minFramebufferCount,
+    imageFormat: DefaultSurfaceFormat(),
+    imageColorSpace: VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, # only one supported without special extensions
+    imageExtent: capabilities.currentExtent,
+    imageArrayLayers: 1,
+    imageUsage: toBits [VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT],
+    imageSharingMode: VK_SHARING_MODE_EXCLUSIVE,
+    preTransform: capabilities.currentTransform,
+    compositeAlpha: VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,  # only used for blending with other windows, can be opaque
+    presentMode: if (vSync or not hasTripleBuffering): VK_PRESENT_MODE_FIFO_KHR else: VK_PRESENT_MODE_MAILBOX_KHR,
+    clipped: true,
+    oldSwapchain: oldSwapchain,
+  )
+  if device.vk.vkCreateSwapchainKHR(addr(createInfo), nil, addr(result)) != VK_SUCCESS:
+    return VkSwapchainKHR(0)
+
+  if samples != VK_SAMPLE_COUNT_1_BIT:
+    vulkan.msaaImage = svkCreate2DImage(
+      width = capabilities.currentExtent.width,
+      height = capabilities.currentExtent.height,
+      format = DefaultSurfaceFormat(),
+      usage = [VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT],
+    )
+    # TODO: memory
+    vk: svkAllocateMemory(size, mType),
+    checkVkResult vkBindImageMemory(
+      vulkan.device,
+      vulkan.msaaImage,
+      selectedBlock.vk,
+      0,
+    )
+
+
+
+    vulkan.msaaImageView = svkCreate2DImageView(vulkan.msaaImageView, DefaultSurfaceFormat())
--- a/semicongine/rendering/vulkan_wrappers.nim	Mon Jul 08 16:15:33 2024 +0700
+++ b/semicongine/rendering/vulkan_wrappers.nim	Mon Jul 08 20:13:11 2024 +0700
@@ -42,6 +42,22 @@
     addr(result),
   )
 
+proc DefaultSurfaceFormat(): VkFormat =
+  # EVERY windows driver and almost every linux driver should support this
+  VK_FORMAT_B8G8R8A8_SRGB
+
+proc svkGetPhysicalDeviceSurfacePresentModesKHR*(): seq[VkPresentModeKHR] =
+  var n_modes: uint32
+  checkVkResult vkGetPhysicalDeviceSurfacePresentModesKHR(vulkan.device, vulkan.surface, addr(n_modes), nil)
+  result = newSeq[VkPresentModeKHR](n_modes)
+  checkVkResult vkGetPhysicalDeviceSurfacePresentModesKHR(vulkan.device, vulkan.surface, addr(n_modes), result.ToCPointer)
+
+proc svkGetPhysicalDeviceSurfaceFormatsKHR()
+  var n_formats: uint32
+  checkVkResult vkGetPhysicalDeviceSurfaceFormatsKHR(vulkan.device, vulkan.surface, addr(n_formats), nil)
+  result = newSeq[VkSurfaceFormatKHR](n_formats)
+  checkVkResult vkGetPhysicalDeviceSurfaceFormatsKHR(vulkan.device, vulkan.surface, addr(n_formats), result.ToCPointer)
+
 proc hasValidationLayer*(): bool =
   var n_layers: uint32
   checkVkResult vkEnumerateInstanceLayerProperties(addr(n_layers), nil)
@@ -111,6 +127,28 @@
   )
   checkVkResult vkCreateImage(vulkan.device, addr imageInfo, nil, addr(result))
 
+proc svkCreate2DImageView(image: VkImage, format: VkFormat): VkImageView =
+  var createInfo = VkImageViewCreateInfo(
+    sType: VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+    image: image,
+    viewType: VK_IMAGE_VIEW_TYPE_2D,
+    format: format,
+    components: VkComponentMapping(
+      r: VK_COMPONENT_SWIZZLE_IDENTITY,
+      g: VK_COMPONENT_SWIZZLE_IDENTITY,
+      b: VK_COMPONENT_SWIZZLE_IDENTITY,
+      a: VK_COMPONENT_SWIZZLE_IDENTITY,
+    ),
+    subresourceRange: VkImageSubresourceRange(
+      aspectMask: VkImageAspectFlags(VK_IMAGE_ASPECT_COLOR_BIT),
+      baseMipLevel: 0,
+      levelCount: 1,
+      baseArrayLayer: 0,
+      layerCount: 1,
+    ),
+  )
+  checkVkResult vkCreateImageView(vulkan.device, addr(createInfo), nil, addr(result))
+
 proc svkGetBufferMemoryRequirements*(buffer: VkBuffer): tuple[size: uint64, alignment: uint64, memoryTypes: seq[uint32]] =
   var reqs: VkMemoryRequirements
   vkGetBufferMemoryRequirements(vulkan.device, buffer, addr(reqs))