changeset 702:8a5521174cc0

fix: separate descriptors per scene
author Sam <sam@basx.dev>
date Sun, 21 May 2023 00:33:38 +0700
parents 26f19ed98701
children 120a1baf2f8d
files src/semicongine/renderer.nim src/semicongine/vulkan/pipeline.nim
diffstat 2 files changed, 8 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/src/semicongine/renderer.nim	Sat May 20 23:26:17 2023 +0700
+++ b/src/semicongine/renderer.nim	Sun May 21 00:33:38 2023 +0700
@@ -29,6 +29,7 @@
     attributeBindingNumber*: Table[string, int]
     transformAttribute: string # name of attribute that is used for per-instance mesh transformation
     entityTransformationCache: Table[Mesh, Mat4] # remembers last transformation, avoid to send GPU-updates if no changes
+    descriptorSets*: Table[VkPipeline, seq[DescriptorSet]]
   Renderer* = object
     device: Device
     surfaceFormat: VkSurfaceFormatKHR
@@ -180,10 +181,9 @@
         let interpolation = images[1]
         for image in images[0]:
           data.textures[name].add renderer.device.createTexture(image.width, image.height, 4, addr image.imagedata[0][0], interpolation)
-      # TODO: this only bind shit to the last scene, find per-scene solution
-      pipeline.setupDescriptors(data.uniformBuffers, data.textures, inFlightFrames=renderer.swapchain.inFlightFrames)
+      data.descriptorSets[pipeline.vk] = pipeline.setupDescriptors(data.uniformBuffers, data.textures, inFlightFrames=renderer.swapchain.inFlightFrames)
       for frame_i in 0 ..< renderer.swapchain.inFlightFrames:
-        pipeline.descriptorSets[frame_i].writeDescriptorSet()
+        data.descriptorSets[pipeline.vk][frame_i].writeDescriptorSet()
 
   renderer.scenedata[scene] = data
 
@@ -254,7 +254,7 @@
     var subpass = renderer.renderPass.subpasses[i]
     for pipeline in subpass.pipelines.mitems:
       commandBuffer.vkCmdBindPipeline(subpass.pipelineBindPoint, pipeline.vk)
-      commandBuffer.vkCmdBindDescriptorSets(subpass.pipelineBindPoint, pipeline.layout, 0, 1, addr(pipeline.descriptorSets[renderer.swapchain.currentInFlight].vk), 0, nil)
+      commandBuffer.vkCmdBindDescriptorSets(subpass.pipelineBindPoint, pipeline.layout, 0, 1, addr(renderer.scenedata[scene].descriptorSets[pipeline.vk][renderer.swapchain.currentInFlight].vk), 0, nil)
 
       debug "Scene buffers:"
       for (location, buffer) in renderer.scenedata[scene].vertexBuffers.pairs:
--- a/src/semicongine/vulkan/pipeline.nim	Sat May 20 23:26:17 2023 +0700
+++ b/src/semicongine/vulkan/pipeline.nim	Sun May 21 00:33:38 2023 +0700
@@ -16,7 +16,6 @@
     shaders*: seq[Shader]
     descriptorSetLayout*: DescriptorSetLayout
     descriptorPool*: DescriptorPool
-    descriptorSets*: seq[DescriptorSet]
 
 func inputs*(pipeline: Pipeline): seq[ShaderAttribute] =
   for shader in pipeline.shaders:
@@ -33,15 +32,16 @@
         result.add attribute
         visitedUniforms[attribute.name] = attribute
 
-proc setupDescriptors*(pipeline: var Pipeline, buffers: seq[Buffer], textures: Table[string, seq[Texture]], inFlightFrames: int) =
+proc setupDescriptors*(pipeline: var Pipeline, buffers: seq[Buffer], textures: Table[string, seq[Texture]], inFlightFrames: int): seq[DescriptorSet] =
   assert pipeline.vk.valid
   assert buffers.len == 0 or buffers.len == inFlightFrames # need to guard against this in case we have no uniforms, then we also create no buffers
-  assert pipeline.descriptorSets.len > 0
+
+  result = pipeline.descriptorPool.allocateDescriptorSet(pipeline.descriptorSetLayout, inFlightFrames)
   
   for i in 0 ..< inFlightFrames:
     var offset = 0'u64
     # first descriptor is always uniform for globals, match should be better somehow
-    for descriptor in pipeline.descriptorSets[i].layout.descriptors.mitems:
+    for descriptor in result[i].layout.descriptors.mitems:
       if descriptor.thetype == Uniform and buffers.len > 0:
         let size = VkDeviceSize(descriptor.size)
         descriptor.buffer = buffers[i]
@@ -198,7 +198,6 @@
     poolsizes.add (VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, uint32(inFlightFrames * vertexShader.samplers.len))
 
   result.descriptorPool = result.device.createDescriptorSetPool(poolsizes)
-  result.descriptorSets = result.descriptorPool.allocateDescriptorSet(result.descriptorSetLayout, inFlightFrames)
   discard result.uniforms # just for assertion