Mercurial > games > semicongine
diff semiconginev2/old/vulkan/pipeline.nim @ 1218:56781cc0fc7c compiletime-tests
did: renamge main package
author | sam <sam@basx.dev> |
---|---|
date | Wed, 17 Jul 2024 21:01:37 +0700 |
parents | semicongine/old/vulkan/pipeline.nim@a3eb305bcac2 |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/semiconginev2/old/vulkan/pipeline.nim Wed Jul 17 21:01:37 2024 +0700 @@ -0,0 +1,203 @@ +import std/tables +import std/sequtils +import std/strformat + +import ../core +import ./device +import ./descriptor +import ./shader +import ./buffer +import ./image + +type + ShaderPipeline* = object + device*: Device + vk*: VkPipeline + layout*: VkPipelineLayout + shaderConfiguration*: ShaderConfiguration + shaderModules*: (ShaderModule, ShaderModule) + descriptorSetLayout*: DescriptorSetLayout + +func Inputs*(pipeline: ShaderPipeline): seq[ShaderAttribute] = + pipeline.shaderConfiguration.inputs + +func Uniforms*(pipeline: ShaderPipeline): seq[ShaderAttribute] = + pipeline.shaderConfiguration.uniforms + +func Samplers*(pipeline: ShaderPipeline): seq[ShaderAttribute] = + pipeline.shaderConfiguration.samplers + +proc SetupDescriptors*(pipeline: ShaderPipeline, descriptorPool: DescriptorPool, buffers: seq[Buffer], textures: var Table[string, seq[VulkanTexture]], inFlightFrames: int, emptyTexture: VulkanTexture): 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 + + result = 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 result[i].layout.descriptors.mitems: + if descriptor.thetype == Uniform and buffers.len > 0: + let size = descriptor.size + descriptor.buffer = buffers[i] + descriptor.offset = offset + descriptor.size = size + offset += size + elif descriptor.thetype == ImageSampler: + if not (descriptor.name in textures): + raise newException(Exception, &"Missing shader texture in scene: {descriptor.name}, available are {textures.keys.toSeq}") + + for textureIndex in 0 ..< int(descriptor.count): + if textureIndex < textures[descriptor.name].len: + descriptor.imageviews.add textures[descriptor.name][textureIndex].imageView + descriptor.samplers.add textures[descriptor.name][textureIndex].sampler + else: + descriptor.imageviews.add emptyTexture.imageView + descriptor.samplers.add emptyTexture.sampler + +proc CreatePipeline*(device: Device, renderPass: VkRenderPass, shaderConfiguration: ShaderConfiguration, inFlightFrames: int, subpass = 0'u32, backFaceCulling = true, samples = VK_SAMPLE_COUNT_1_BIT): ShaderPipeline = + assert renderPass.Valid + assert device.vk.Valid + + result.device = device + result.shaderModules = device.CreateShaderModules(shaderConfiguration) + result.shaderConfiguration = shaderConfiguration + + var descriptors: seq[Descriptor] + if result.shaderConfiguration.uniforms.len > 0: + descriptors.add Descriptor( + name: "Uniforms", + thetype: Uniform, + count: 1, + stages: @[VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT], + size: result.shaderConfiguration.uniforms.Size(), + ) + for sampler in result.shaderConfiguration.samplers: + descriptors.add Descriptor( + name: sampler.name, + thetype: ImageSampler, + count: (if sampler.arrayCount == 0: 1 else: sampler.arrayCount), + stages: @[VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT], + ) + result.descriptorSetLayout = device.CreateDescriptorSetLayout(descriptors) + + # TODO: Push constants + # var pushConstant = VkPushConstantRange( + # stageFlags: toBits shaderStage, + # offset: 0, + # size: 0, + # ) + var descriptorSetLayouts: seq[VkDescriptorSetLayout] = @[result.descriptorSetLayout.vk] + # var pushConstants: seq[VkPushConstantRange] = @[pushConstant] + var pipelineLayoutInfo = VkPipelineLayoutCreateInfo( + sType: VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + setLayoutCount: uint32(descriptorSetLayouts.len), + pSetLayouts: descriptorSetLayouts.ToCPointer, + # pushConstantRangeCount: uint32(pushConstants.len), + # pPushConstantRanges: pushConstants.ToCPointer, + ) + checkVkResult vkCreatePipelineLayout(device.vk, addr(pipelineLayoutInfo), nil, addr(result.layout)) + + var + bindings: seq[VkVertexInputBindingDescription] + attributes: seq[VkVertexInputAttributeDescription] + vertexInputInfo = result.shaderConfiguration.GetVertexInputInfo(bindings, attributes) + inputAssembly = VkPipelineInputAssemblyStateCreateInfo( + sType: VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, + topology: VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, + primitiveRestartEnable: VK_FALSE, + ) + viewportState = VkPipelineViewportStateCreateInfo( + sType: VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, + viewportCount: 1, + scissorCount: 1, + ) + rasterizer = VkPipelineRasterizationStateCreateInfo( + sType: VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, + depthClampEnable: VK_FALSE, + rasterizerDiscardEnable: VK_FALSE, + polygonMode: VK_POLYGON_MODE_FILL, + lineWidth: 1.0, + cullMode: if backFaceCulling: toBits [VK_CULL_MODE_BACK_BIT] else: VkCullModeFlags(0), + frontFace: VK_FRONT_FACE_CLOCKWISE, + depthBiasEnable: VK_FALSE, + depthBiasConstantFactor: 0.0, + depthBiasClamp: 0.0, + depthBiasSlopeFactor: 0.0, + ) + multisampling = VkPipelineMultisampleStateCreateInfo( + sType: VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, + sampleShadingEnable: VK_FALSE, + rasterizationSamples: samples, + minSampleShading: 1.0, + pSampleMask: nil, + alphaToCoverageEnable: VK_FALSE, + alphaToOneEnable: VK_FALSE, + ) + colorBlendAttachment = VkPipelineColorBlendAttachmentState( + colorWriteMask: toBits [VK_COLOR_COMPONENT_R_BIT, VK_COLOR_COMPONENT_G_BIT, VK_COLOR_COMPONENT_B_BIT, VK_COLOR_COMPONENT_A_BIT], + blendEnable: VK_TRUE, + srcColorBlendFactor: VK_BLEND_FACTOR_SRC_ALPHA, + dstColorBlendFactor: VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + colorBlendOp: VK_BLEND_OP_ADD, + srcAlphaBlendFactor: VK_BLEND_FACTOR_ONE, + dstAlphaBlendFactor: VK_BLEND_FACTOR_ZERO, + alphaBlendOp: VK_BLEND_OP_ADD, + ) + colorBlending = VkPipelineColorBlendStateCreateInfo( + sType: VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, + logicOpEnable: false, + attachmentCount: 1, + pAttachments: addr(colorBlendAttachment), + ) + dynamicStates = @[VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR] + dynamicState = VkPipelineDynamicStateCreateInfo( + sType: VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, + dynamicStateCount: uint32(dynamicStates.len), + pDynamicStates: dynamicStates.ToCPointer, + ) + stages = @[result.shaderModules[0].GetPipelineInfo(), result.shaderModules[1].GetPipelineInfo()] + createInfo = VkGraphicsPipelineCreateInfo( + sType: VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, + stageCount: uint32(stages.len), + pStages: stages.ToCPointer, + pVertexInputState: addr(vertexInputInfo), + pInputAssemblyState: addr(inputAssembly), + pViewportState: addr(viewportState), + pRasterizationState: addr(rasterizer), + pMultisampleState: addr(multisampling), + pDepthStencilState: nil, + pColorBlendState: addr(colorBlending), + pDynamicState: addr(dynamicState), + layout: result.layout, + renderPass: renderPass, + subpass: subpass, + basePipelineHandle: VkPipeline(0), + basePipelineIndex: -1, + ) + checkVkResult vkCreateGraphicsPipelines( + device.vk, + VkPipelineCache(0), + 1, + addr(createInfo), + nil, + addr(result.vk) + ) + + discard result.Uniforms # just for assertion + + +proc Destroy*(pipeline: var ShaderPipeline) = + assert pipeline.device.vk.Valid + assert pipeline.vk.Valid + assert pipeline.layout.Valid + assert pipeline.descriptorSetLayout.vk.Valid + + pipeline.shaderModules[0].Destroy() + pipeline.shaderModules[1].Destroy() + pipeline.descriptorSetLayout.Destroy() + pipeline.device.vk.vkDestroyPipelineLayout(pipeline.layout, nil) + pipeline.device.vk.vkDestroyPipeline(pipeline.vk, nil) + pipeline.descriptorSetLayout.vk.Reset() + pipeline.layout.Reset() + pipeline.vk.Reset()