changeset 1198:96a094cd0c78 compiletime-tests

sync to notebook in bedroom
author sam <sam@basx.dev>
date Sat, 13 Jul 2024 19:26:03 +0700
parents f6a0dc7ad052
children ba1af13233ee
files semicongine/rendering.nim semicongine/rendering/swapchain.nim semicongine/rendering/vulkan_wrappers.nim test1.nim
diffstat 4 files changed, 76 insertions(+), 63 deletions(-) [+]
line wrap: on
line diff
--- a/semicongine/rendering.nim	Fri Jul 12 23:06:29 2024 +0700
+++ b/semicongine/rendering.nim	Sat Jul 13 19:26:03 2024 +0700
@@ -49,11 +49,14 @@
     msaaImageView: VkImageView
     framebuffers: seq[VkFramebuffer]
     framebufferViews: seq[VkImageView]
+    currentFramebufferIndex: uint32
+    commandBufferPool: VkCommandPool
+    # frame-in-flight handling
+    currentFiF: range[0 .. (INFLIGHTFRAMES - 1).int]
     queueFinishedFence*: array[INFLIGHTFRAMES.int, VkFence]
     imageAvailableSemaphore*: array[INFLIGHTFRAMES.int, VkSemaphore]
     renderFinishedSemaphore*: array[INFLIGHTFRAMES.int, VkSemaphore]
-    currentFiF: range[0 .. (INFLIGHTFRAMES - 1).int]
-    currentFramebufferIndex: uint32
+    commandBuffers: array[INFLIGHTFRAMES.int, VkCommandBuffer]
 
 var vulkan*: VulkanGlobals
 
@@ -167,10 +170,12 @@
   include ./platform/vulkan_extensions # for REQUIRED_PLATFORM_EXTENSIONS
 
   # instance creation
-  #
+
+  # enagle all kind of debug stuff
   when not defined(release):
     let requiredExtensions = REQUIRED_PLATFORM_EXTENSIONS & @["VK_KHR_surface", "VK_EXT_debug_utils"]
     let layers: seq[string] = if hasValidationLayer(): @["VK_LAYER_KHRONOS_validation"] else: @[]
+    putEnv("VK_LAYER_ENABLES", "VALIDATION_CHECK_ENABLE_VENDOR_SPECIFIC_AMD,VALIDATION_CHECK_ENABLE_VENDOR_SPECIFIC_NVIDIA,VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXTVK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT,VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT")
   else:
     let requiredExtensions = REQUIRED_PLATFORM_EXTENSIONS & @["VK_KHR_surface"]
     let layers: seq[string]
--- a/semicongine/rendering/swapchain.nim	Fri Jul 12 23:06:29 2024 +0700
+++ b/semicongine/rendering/swapchain.nim	Sat Jul 13 19:26:03 2024 +0700
@@ -4,7 +4,6 @@
   renderPass: VkRenderPass,
   vSync: bool = false,
   samples = VK_SAMPLE_COUNT_1_BIT,
-  nFramebuffers = N_FRAMEBUFFERS,
   oldSwapchain = VkSwapchainKHR(0),
 ): Option[Swapchain] =
   assert vulkan.instance.Valid
@@ -27,7 +26,7 @@
 
   # create swapchain
   let hasTripleBuffering = VK_PRESENT_MODE_MAILBOX_KHR in svkGetPhysicalDeviceSurfacePresentModesKHR()
-  var createInfo = VkSwapchainCreateInfoKHR(
+  var swapchainCreateInfo = VkSwapchainCreateInfoKHR(
     sType: VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
     surface: vulkan.surface,
     minImageCount: minFramebufferCount,
@@ -44,7 +43,7 @@
     oldSwapchain: oldSwapchain,
   )
   var swapchain: Swapchain
-  if vkCreateSwapchainKHR(vulkan.device, addr(createInfo), nil, addr(swapchain.vk)) != VK_SUCCESS:
+  if vkCreateSwapchainKHR(vulkan.device, addr(swapchainCreateInfo), nil, addr(swapchain.vk)) != VK_SUCCESS:
     return none(Swapchain)
 
   swapchain.renderPass = renderPass
@@ -90,9 +89,25 @@
     swapchain.queueFinishedFence[i] = svkCreateFence(signaled = true)
     swapchain.imageAvailableSemaphore[i] = svkCreateSemaphore()
     swapchain.renderFinishedSemaphore[i] = svkCreateSemaphore()
+
+  # command buffers
+  var commandPoolCreateInfo = VkCommandPoolCreateInfo(
+    sType: VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
+    flags: toBits [VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT],
+    queueFamilyIndex: vulkan.graphicsQueueFamily,
+  )
+  checkVkResult vkCreateCommandPool(vulkan.device, addr(commandPoolCreateInfo), nil, addr(swapchain.commandBufferPool))
+  var allocInfo = VkCommandBufferAllocateInfo(
+    sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
+    commandPool: swapchain.commandBufferPool,
+    level: VK_COMMAND_BUFFER_LEVEL_PRIMARY,
+    commandBufferCount: INFLIGHTFRAMES,
+  )
+  checkVkResult vkAllocateCommandBuffers(vulkan.device, addr(allocInfo), swapchain.commandBuffers.ToCPointer)
+
   return some(swapchain)
 
-proc TryAcquireNextImage*(swapchain: var Swapchain): Option[VkFramebuffer] =
+proc TryAcquireNextImage(swapchain: var Swapchain): Option[VkFramebuffer] =
   swapchain.queueFinishedFence[swapchain.currentFiF].Await()
 
   let nextImageResult = vkAcquireNextImageKHR(
@@ -110,7 +125,7 @@
     return none(VkFramebuffer)
   return some(swapchain.framebuffers[swapchain.currentFramebufferIndex])
 
-proc Swap*(swapchain: var Swapchain, queue: VkQueue, commandBuffer: VkCommandBuffer): bool =
+proc Swap(swapchain: var Swapchain, commandBuffer: VkCommandBuffer): bool =
   var
     waitStage = VkPipelineStageFlags(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT)
     submitInfo = VkSubmitInfo(
@@ -124,7 +139,7 @@
       pSignalSemaphores: addr(swapchain.renderFinishedSemaphore[swapchain.currentFiF]),
     )
   checkVkResult vkQueueSubmit(
-    queue = queue,
+    queue = vulkan.graphicsQueue,
     submitCount = 1,
     pSubmits = addr(submitInfo),
     fence = swapchain.queueFinishedFence[swapchain.currentFiF]
@@ -143,13 +158,47 @@
   if presentResult != VK_SUCCESS:
     return false
 
+  swapchain.currentFiF = (uint32(swapchain.currentFiF) + 1) mod INFLIGHTFRAMES
   return true
 
-proc Recreate*(swapchain: Swapchain): Option[Swapchain] =
+proc Recreate(swapchain: Swapchain): Option[Swapchain] =
   InitSwapchain(
     renderPass = swapchain.renderPass,
     vSync = swapchain.vSync,
     samples = swapchain.samples,
-    nFramebuffers = swapchain.framebuffers.len.uint32,
     oldSwapchain = swapchain.vk,
   )
+
+template RecordRenderingCommands*(swapchain: var Swapchain, framebufferName, commandBufferName, body: untyped): untyped =
+  var nextFrameReady = true
+
+  var maybeFramebuffer = TryAcquireNextImage(swapchain)
+  if not maybeFramebuffer.isSome:
+    let maybeNewSwapchain = Recreate(swapchain)
+    # unable to recreate swapchain
+    if not maybeNewSwapchain.isSome:
+      nextFrameReady = false
+    else:
+      swapchain = maybeNewSwapchain.get
+      maybeFramebuffer = TryAcquireNextImage(swapchain)
+      if not maybeFramebuffer.isSome:
+        nextFrameReady = false
+
+  if nextFrameReady:
+    block:
+      let `framebufferName` {.inject.} = maybeFramebuffer.get
+      let `commandBufferName` {.inject.} = swapchain.commandBuffers[swapchain.currentFiF]
+      let beginInfo = VkCommandBufferBeginInfo(
+        sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
+        flags: VkCommandBufferUsageFlags(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT),
+      )
+      checkVkResult vkResetCommandBuffer(`commandBufferName`, VkCommandBufferResetFlags(0))
+      checkVkResult vkBeginCommandBuffer(`commandBufferName`, addr(beginInfo))
+
+      body
+
+      checkVkResult vkEndCommandBuffer(`commandBufferName`)
+      if not Swap(swapchain = swapchain, commandBuffer = `commandBufferName`):
+        let maybeNewSwapchain = Recreate(swapchain)
+        if maybeNewSwapchain.isSome:
+          swapchain = maybeNewSwapchain.get
--- a/semicongine/rendering/vulkan_wrappers.nim	Fri Jul 12 23:06:29 2024 +0700
+++ b/semicongine/rendering/vulkan_wrappers.nim	Sat Jul 13 19:26:03 2024 +0700
@@ -235,7 +235,7 @@
       commandBufferPool: VkCommandPool
       createInfo = VkCommandPoolCreateInfo(
         sType: VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
-        flags: toBits [VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT],
+        flags: VkCommandPoolCreateFlags(0),
         queueFamilyIndex: vulkan.graphicsQueueFamily,
       )
     checkVkResult vkCreateCommandPool(vulkan.device, addr createInfo, nil, addr(commandBufferPool))
--- a/test1.nim	Fri Jul 12 23:06:29 2024 +0700
+++ b/test1.nim	Sat Jul 13 19:26:03 2024 +0700
@@ -41,8 +41,6 @@
     vertexCode: string = "void main() {}"
     fragmentCode: string = "void main() {}"
 
-putEnv("VK_LAYER_ENABLES", "VALIDATION_CHECK_ENABLE_VENDOR_SPECIFIC_AMD,VALIDATION_CHECK_ENABLE_VENDOR_SPECIFIC_NVIDIA,VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXTVK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT,VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT")
-
 let frameWidth = 100'u32
 let frameHeight = 100'u32
 
@@ -76,7 +74,7 @@
 )
 
 let renderpass = CreatePresentationRenderPass()
-var swapchainResult = InitSwapchain(renderpass)
+var swapchainResult = InitSwapchain(renderpass = renderpass)
 assert swapchainResult.isSome()
 var swapchain = swapchainResult.get()
 
@@ -104,59 +102,21 @@
 UpdateAllGPUBuffers(myGlobals)
 renderdata.FlushAllMemory()
 
-
 # descriptors
 echo "Writing descriptors"
 InitDescriptorSet(renderdata, pipeline1.GetLayoutFor(GlobalSet), myGlobals)
 InitDescriptorSet(renderdata, pipeline1.GetLayoutFor(MaterialSet), uniforms1)
 
 
-
-
-
-
-# command buffer
-var
-  commandBufferPool: VkCommandPool
-  createInfo = VkCommandPoolCreateInfo(
-    sType: VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
-    flags: toBits [VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT],
-    queueFamilyIndex: vulkan.graphicsQueueFamily,
-  )
-checkVkResult vkCreateCommandPool(vulkan.device, addr createInfo, nil, addr commandBufferPool)
-var
-  cmdBuffers: array[INFLIGHTFRAMES.int, VkCommandBuffer]
-  allocInfo = VkCommandBufferAllocateInfo(
-    sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
-    commandPool: commandBufferPool,
-    level: VK_COMMAND_BUFFER_LEVEL_PRIMARY,
-    commandBufferCount: INFLIGHTFRAMES,
-  )
-checkVkResult vkAllocateCommandBuffers(vulkan.device, addr allocInfo, cmdBuffers.ToCPointer)
-
-
-
 # start command buffer
-block:
-  let
-    currentFramebuffer = VkFramebuffer(0) # TODO
-    currentFrameInFlight = 1
-    cmd = cmdBuffers[currentFrameInFlight]
-    beginInfo = VkCommandBufferBeginInfo(
-      sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
-      flags: VkCommandBufferUsageFlags(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT),
-    )
-  checkVkResult cmd.vkResetCommandBuffer(VkCommandBufferResetFlags(0))
-  checkVkResult cmd.vkBeginCommandBuffer(addr(beginInfo))
-
-  # start renderpass
-  block:
+while true:
+  RecordRenderingCommands(swapchain, framebuffer, commandbuffer):
     var
       clearColors = [VkClearValue(color: VkClearColorValue(float32: [0, 0, 0, 0]))]
       renderPassInfo = VkRenderPassBeginInfo(
         sType: VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
         renderPass: renderpass,
-        framebuffer: currentFramebuffer, # TODO
+        framebuffer: framebuffer,
         renderArea: VkRect2D(
           offset: VkOffset2D(x: 0, y: 0),
           extent: VkExtent2D(width: frameWidth, height: frameHeight),
@@ -176,19 +136,18 @@
         offset: VkOffset2D(x: 0, y: 0),
         extent: VkExtent2D(width: frameWidth, height: frameHeight)
       )
-    vkCmdBeginRenderPass(cmd, addr(renderPassInfo), VK_SUBPASS_CONTENTS_INLINE)
+    vkCmdBeginRenderPass(commandbuffer, addr(renderPassInfo), VK_SUBPASS_CONTENTS_INLINE)
 
     # setup viewport
-    vkCmdSetViewport(cmd, firstViewport = 0, viewportCount = 1, addr(viewport))
-    vkCmdSetScissor(cmd, firstScissor = 0, scissorCount = 1, addr(scissor))
+    vkCmdSetViewport(commandbuffer, firstViewport = 0, viewportCount = 1, addr(viewport))
+    vkCmdSetScissor(commandbuffer, firstScissor = 0, scissorCount = 1, addr(scissor))
 
     # bind pipeline, will be loop
     # block:
-      # Bind(pipeline1, cmd, currentFrameInFlight = currentFrameInFlight)
+      # Bind(pipeline1, commandbuffer, currentFrameInFlight = currentFrameInFlight)
 
       # render object, will be loop
       # block:
-        # Render(cmd, pipeline1, myGlobals, uniforms1, myMesh1, instances1)
+        # Render(commandbuffer, pipeline1, myGlobals, uniforms1, myMesh1, instances1)
 
-    vkCmdEndRenderPass(cmd)
-  checkVkResult cmd.vkEndCommandBuffer()
+    vkCmdEndRenderPass(commandbuffer)