# HG changeset patch # User Sam # Date 1684604018 -25200 # Node ID 671b9267a5332c23819e5097fca1127b49dec23d # Parent 4f17d04b8291b2f40df4e4b86fc4c96511819852 fix: separate descriptors per scene diff -r 4f17d04b8291 -r 671b9267a533 src/semicongine/renderer.nim --- 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: diff -r 4f17d04b8291 -r 671b9267a533 src/semicongine/vulkan/pipeline.nim --- 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