changeset 110:3bbc94a83404

add: multiple pipelines per subpass
author Sam <sam@basx.dev>
date Thu, 30 Mar 2023 00:00:54 +0700
parents 8d24727c9795
children 6fd10b7e2d6a
files src/semicongine/scene.nim src/semicongine/vulkan/pipeline.nim src/semicongine/vulkan/renderpass.nim src/semicongine/vulkan/swapchain.nim
diffstat 4 files changed, 45 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/src/semicongine/scene.nim	Wed Mar 29 23:35:39 2023 +0700
+++ b/src/semicongine/scene.nim	Thu Mar 30 00:00:54 2023 +0700
@@ -5,9 +5,21 @@
 import ./vulkan/buffer
 
 type
+  Drawable* = object
+    buffers*: seq[Buffer]
+    elementCount*: uint32
+    instanceCount*: uint32
+    case indexed*: bool
+    of true:
+      indexBuffer*: Buffer
+      indexType*: VkIndexType
+    of false:
+      discard
+
   Scene* = object
     root*: Entity
+    drawables: seq[Drawable]
 
-# attribute_buffers, number_of_vertices, number_of_instances, (indexbuffer, indextype)
-proc getBufferSets*(scene: Scene): seq[(seq[Buffer], uint32, uint32, Option[(Buffer, VkIndexType)])] =
+proc getDrawables*(scene: Scene): seq[Drawable] =
+  # TODO: create and fill buffers
   result
--- a/src/semicongine/vulkan/pipeline.nim	Wed Mar 29 23:35:39 2023 +0700
+++ b/src/semicongine/vulkan/pipeline.nim	Thu Mar 30 00:00:54 2023 +0700
@@ -20,20 +20,34 @@
   var varPipeline = pipeline
   commandBuffer.vkCmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.vk)
   commandBuffer.vkCmdBindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.layout, 0, 1, addr(varPipeline.descriptorSets[inFlightFrame].vk), 0, nil)
-  for (bufferSet, count, instanceCount, indexBuffer) in scene.getBufferSets():
+  for drawable in scene.getDrawables():
     var buffers: seq[VkBuffer]
     var offsets: seq[VkDeviceSize]
-    for buffer in bufferSet:
+    for buffer in drawable.buffers:
       buffers.add buffer.vk
       offsets.add VkDeviceSize(0)
-
-    commandBuffer.vkCmdBindVertexBuffers(firstBinding=0'u32, bindingCount=uint32(buffers.len), pBuffers=buffers.toCPointer(), pOffsets=offsets.toCPointer())
-    if indexBuffer.isSome:
-      commandBuffer.vkCmdBindIndexBuffer(indexBuffer.get()[0].vk, VkDeviceSize(0), indexBuffer.get()[1])
-      commandBuffer.vkCmdDrawIndexed(indexCount=count, instanceCount=instanceCount, firstIndex=0, vertexOffset=0, firstInstance=0)
-
+    commandBuffer.vkCmdBindVertexBuffers(
+      firstBinding=0'u32,
+      bindingCount=uint32(buffers.len),
+      pBuffers=buffers.toCPointer(),
+      pOffsets=offsets.toCPointer()
+    )
+    if drawable.indexed:
+      commandBuffer.vkCmdBindIndexBuffer(drawable.indexBuffer.vk, VkDeviceSize(0), drawable.indexType)
+      commandBuffer.vkCmdDrawIndexed(
+        indexCount=drawable.elementCount,
+        instanceCount=drawable.instanceCount,
+        firstIndex=0,
+        vertexOffset=0,
+        firstInstance=0
+      )
     else:
-      commandBuffer.vkCmdDraw(vertexCount=count, instanceCount=instanceCount, firstVertex=0, firstInstance=0)
+      commandBuffer.vkCmdDraw(
+        vertexCount=drawable.elementCount,
+        instanceCount=drawable.instanceCount,
+        firstVertex=0,
+        firstInstance=0
+      )
 
 proc destroy*(pipeline: var Pipeline) =
   assert pipeline.device.vk.valid
--- a/src/semicongine/vulkan/renderpass.nim	Wed Mar 29 23:35:39 2023 +0700
+++ b/src/semicongine/vulkan/renderpass.nim	Thu Mar 30 00:00:54 2023 +0700
@@ -18,12 +18,12 @@
     resolvers: seq[VkAttachmentReference]
     depthStencil: Option[VkAttachmentReference]
     preserves: seq[uint32]
+    pipelines*: seq[Pipeline]
   RenderPass* = object
     vk*: VkRenderPass
     device*: Device
     inFlightFrames*: int
     subpasses*: seq[Subpass]
-    pipelines*: seq[Pipeline]
 
 proc createRenderPass*(
   device: Device,
@@ -64,7 +64,6 @@
   result.device = device
   result.inFlightFrames = inFlightFrames
   result.subpasses = pSubpasses
-  result.pipelines = newSeq[Pipeline](pSubpasses.len)
   checkVkResult device.vk.vkCreateRenderPass(addr(createInfo), nil, addr(result.vk))
 
 proc attachPipeline[VertexShader: Shader, FragmentShader: Shader](renderPass: var RenderPass, vertexShader: VertexShader, fragmentShader: FragmentShader, subpass = 0'u32) =
@@ -196,7 +195,7 @@
   )
   pipeline.descriptorPool = pipeline.device.createDescriptorSetPool(@[(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1'u32)])
   pipeline.descriptorSets = pipeline.descriptorPool.allocateDescriptorSet(pipeline.descriptorSetLayout, renderPass.inFlightFrames)
-  renderPass.pipelines[subpass] = pipeline
+  renderPass.subpasses[subpass].pipelines.add pipeline
 
 proc simpleForwardRenderPass*[VertexShader: Shader, FragmentShader: Shader](device: Device, format: VkFormat, vertexShader: VertexShader, fragmentShader: FragmentShader, inFlightFrames: int, clearColor=Vec4([0.5'f32, 0.5'f32, 0.5'f32, 1'f32])): RenderPass =
   assert device.vk.valid
@@ -235,6 +234,7 @@
   assert renderpass.vk.valid
   renderpass.device.vk.vkDestroyRenderPass(renderpass.vk, nil)
   renderpass.vk.reset
-  for pipeline in renderpass.pipelines.mitems:
-    pipeline.destroy()
-  renderpass.pipelines = @[]
+  for subpass in renderpass.subpasses.mitems:
+    for pipeline in subpass.pipelines.mitems:
+      pipeline.destroy()
+  renderpass.subpasses = @[]
--- a/src/semicongine/vulkan/swapchain.nim	Wed Mar 29 23:35:39 2023 +0700
+++ b/src/semicongine/vulkan/swapchain.nim	Thu Mar 30 00:00:54 2023 +0700
@@ -131,8 +131,8 @@
     swapchain.framebuffers[currentFramebufferIndex]
   ):
     for i in 0 ..< swapchain.renderpass.subpasses.len:
-      var pipeline = swapchain.renderpass.pipelines[i]
-      pipeline.run(commandBuffer, swapchain.currentInFlight, scene)
+      for pipeline in swapchain.renderpass.subpasses[i].pipelines:
+        pipeline.run(commandBuffer, swapchain.currentInFlight, scene)
       if i < swapchain.renderpass.subpasses.len - 1:
         commandBuffer.vkCmdNextSubpass(VK_SUBPASS_CONTENTS_INLINE)