diff --git a/src/CommandBuffer.hs b/src/CommandBuffer.hs index 687697b..188d568 100644 --- a/src/CommandBuffer.hs +++ b/src/CommandBuffer.hs @@ -101,6 +101,12 @@ createFrames Vk.BUFFER_USAGE_STORAGE_BUFFER_BIT VMA.MEMORY_USAGE_CPU_TO_GPU + indirectBuffer <- createAllocatedBuffer + allocator + (sizeOf maxObjects) + Vk.BUFFER_USAGE_STORAGE_BUFFER_BIT + VMA.MEMORY_USAGE_CPU_TO_GPU + let allocationInfo = Vk.zero { Vk.descriptorPool = descriptorPool , Vk.setLayouts = V.singleton setLayout @@ -162,6 +168,7 @@ createFrames , frameCameraBuffer = cameraBuffer , frameSceneBuffer = sceneBuffer , frameObjectBuffer = objectBuffer + , frameIndirectBuffer = indirectBuffer , frameGlobalDescriptor = V.head globalDescriptor , frameObjectDescriptor = V.head objectDescriptor } @@ -226,6 +233,71 @@ recordCommandBuffer let draws = compactDraws meshMap materialMap renderObjects + let drawCommands = V.map + (\(i, RenderObject mesh matrix material) -> + Vk.DrawIndirectCommand + { vertexCount = fromIntegral (V.length $ meshVertices $ meshMap M.! mesh) + , firstVertex = 0 + , instanceCount = 1 + , firstInstance = i + } + ) + (V.zip + (V.fromList [0..]) + renderObjects + ) + + V.mapM_ + (\(IndirectBatch mesh material first count) -> do + + when + (materialTextureSet material /= Vk.NULL_HANDLE) + (Vk.cmdBindDescriptorSets + commandBuffer + Vk.PIPELINE_BIND_POINT_GRAPHICS + (materialPipelineLayout material) + 2 + (V.singleton $ materialTextureSet material) + V.empty + ) + + Vk.cmdBindPipeline commandBuffer Vk.PIPELINE_BIND_POINT_GRAPHICS (materialPipeline material) + + Vk.cmdBindDescriptorSets + commandBuffer + Vk.PIPELINE_BIND_POINT_GRAPHICS + (materialPipelineLayout material) + 0 + (V.singleton $ frameGlobalDescriptor frame) + V.empty + + Vk.cmdBindDescriptorSets + commandBuffer + Vk.PIPELINE_BIND_POINT_GRAPHICS + (materialPipelineLayout material) + 1 + (V.singleton $ frameObjectDescriptor frame) + V.empty + + Vk.cmdBindVertexBuffers + commandBuffer + 0 + (V.fromList [ allocatedBuffer $ meshBuffer mesh ]) + (V.fromList [ 0 ]) + + let indirectOffset = fromIntegral $ + first * fromIntegral ( sizeOf (undefined :: Vk.DrawIndirectCommand)) + drawStride = fromIntegral $ sizeOf (undefined :: Vk.DrawIndirectCommand) + + Vk.cmdDrawIndirect + commandBuffer + (allocatedBuffer $ frameIndirectBuffer frame) + indirectOffset + (fromIntegral $ V.length draws) + drawStride + ) + draws + V.mapM_ (\(IndirectBatch mesh material first count) -> do diff --git a/src/Types.hs b/src/Types.hs index abeb025..a33590c 100644 --- a/src/Types.hs +++ b/src/Types.hs @@ -227,6 +227,7 @@ data FrameData = FrameData , frameCameraBuffer :: AllocatedBuffer , frameSceneBuffer :: AllocatedBuffer , frameObjectBuffer :: AllocatedBuffer + , frameIndirectBuffer :: AllocatedBuffer , frameGlobalDescriptor :: Vk.DescriptorSet , frameObjectDescriptor :: Vk.DescriptorSet }