Mercurial > games > semicongine
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 1217:f819a874058f | 1218:56781cc0fc7c |
|---|---|
| 1 import std/tables | |
| 2 import std/sequtils | |
| 3 import std/strformat | |
| 4 | |
| 5 import ../core | |
| 6 import ./device | |
| 7 import ./descriptor | |
| 8 import ./shader | |
| 9 import ./buffer | |
| 10 import ./image | |
| 11 | |
| 12 type | |
| 13 ShaderPipeline* = object | |
| 14 device*: Device | |
| 15 vk*: VkPipeline | |
| 16 layout*: VkPipelineLayout | |
| 17 shaderConfiguration*: ShaderConfiguration | |
| 18 shaderModules*: (ShaderModule, ShaderModule) | |
| 19 descriptorSetLayout*: DescriptorSetLayout | |
| 20 | |
| 21 func Inputs*(pipeline: ShaderPipeline): seq[ShaderAttribute] = | |
| 22 pipeline.shaderConfiguration.inputs | |
| 23 | |
| 24 func Uniforms*(pipeline: ShaderPipeline): seq[ShaderAttribute] = | |
| 25 pipeline.shaderConfiguration.uniforms | |
| 26 | |
| 27 func Samplers*(pipeline: ShaderPipeline): seq[ShaderAttribute] = | |
| 28 pipeline.shaderConfiguration.samplers | |
| 29 | |
| 30 proc SetupDescriptors*(pipeline: ShaderPipeline, descriptorPool: DescriptorPool, buffers: seq[Buffer], textures: var Table[string, seq[VulkanTexture]], inFlightFrames: int, emptyTexture: VulkanTexture): seq[DescriptorSet] = | |
| 31 assert pipeline.vk.Valid | |
| 32 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 | |
| 33 | |
| 34 result = descriptorPool.AllocateDescriptorSet(pipeline.descriptorSetLayout, inFlightFrames) | |
| 35 | |
| 36 for i in 0 ..< inFlightFrames: | |
| 37 var offset = 0'u64 | |
| 38 # first descriptor is always uniform for globals, match should be better somehow | |
| 39 for descriptor in result[i].layout.descriptors.mitems: | |
| 40 if descriptor.thetype == Uniform and buffers.len > 0: | |
| 41 let size = descriptor.size | |
| 42 descriptor.buffer = buffers[i] | |
| 43 descriptor.offset = offset | |
| 44 descriptor.size = size | |
| 45 offset += size | |
| 46 elif descriptor.thetype == ImageSampler: | |
| 47 if not (descriptor.name in textures): | |
| 48 raise newException(Exception, &"Missing shader texture in scene: {descriptor.name}, available are {textures.keys.toSeq}") | |
| 49 | |
| 50 for textureIndex in 0 ..< int(descriptor.count): | |
| 51 if textureIndex < textures[descriptor.name].len: | |
| 52 descriptor.imageviews.add textures[descriptor.name][textureIndex].imageView | |
| 53 descriptor.samplers.add textures[descriptor.name][textureIndex].sampler | |
| 54 else: | |
| 55 descriptor.imageviews.add emptyTexture.imageView | |
| 56 descriptor.samplers.add emptyTexture.sampler | |
| 57 | |
| 58 proc CreatePipeline*(device: Device, renderPass: VkRenderPass, shaderConfiguration: ShaderConfiguration, inFlightFrames: int, subpass = 0'u32, backFaceCulling = true, samples = VK_SAMPLE_COUNT_1_BIT): ShaderPipeline = | |
| 59 assert renderPass.Valid | |
| 60 assert device.vk.Valid | |
| 61 | |
| 62 result.device = device | |
| 63 result.shaderModules = device.CreateShaderModules(shaderConfiguration) | |
| 64 result.shaderConfiguration = shaderConfiguration | |
| 65 | |
| 66 var descriptors: seq[Descriptor] | |
| 67 if result.shaderConfiguration.uniforms.len > 0: | |
| 68 descriptors.add Descriptor( | |
| 69 name: "Uniforms", | |
| 70 thetype: Uniform, | |
| 71 count: 1, | |
| 72 stages: @[VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT], | |
| 73 size: result.shaderConfiguration.uniforms.Size(), | |
| 74 ) | |
| 75 for sampler in result.shaderConfiguration.samplers: | |
| 76 descriptors.add Descriptor( | |
| 77 name: sampler.name, | |
| 78 thetype: ImageSampler, | |
| 79 count: (if sampler.arrayCount == 0: 1 else: sampler.arrayCount), | |
| 80 stages: @[VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT], | |
| 81 ) | |
| 82 result.descriptorSetLayout = device.CreateDescriptorSetLayout(descriptors) | |
| 83 | |
| 84 # TODO: Push constants | |
| 85 # var pushConstant = VkPushConstantRange( | |
| 86 # stageFlags: toBits shaderStage, | |
| 87 # offset: 0, | |
| 88 # size: 0, | |
| 89 # ) | |
| 90 var descriptorSetLayouts: seq[VkDescriptorSetLayout] = @[result.descriptorSetLayout.vk] | |
| 91 # var pushConstants: seq[VkPushConstantRange] = @[pushConstant] | |
| 92 var pipelineLayoutInfo = VkPipelineLayoutCreateInfo( | |
| 93 sType: VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, | |
| 94 setLayoutCount: uint32(descriptorSetLayouts.len), | |
| 95 pSetLayouts: descriptorSetLayouts.ToCPointer, | |
| 96 # pushConstantRangeCount: uint32(pushConstants.len), | |
| 97 # pPushConstantRanges: pushConstants.ToCPointer, | |
| 98 ) | |
| 99 checkVkResult vkCreatePipelineLayout(device.vk, addr(pipelineLayoutInfo), nil, addr(result.layout)) | |
| 100 | |
| 101 var | |
| 102 bindings: seq[VkVertexInputBindingDescription] | |
| 103 attributes: seq[VkVertexInputAttributeDescription] | |
| 104 vertexInputInfo = result.shaderConfiguration.GetVertexInputInfo(bindings, attributes) | |
| 105 inputAssembly = VkPipelineInputAssemblyStateCreateInfo( | |
| 106 sType: VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, | |
| 107 topology: VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, | |
| 108 primitiveRestartEnable: VK_FALSE, | |
| 109 ) | |
| 110 viewportState = VkPipelineViewportStateCreateInfo( | |
| 111 sType: VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, | |
| 112 viewportCount: 1, | |
| 113 scissorCount: 1, | |
| 114 ) | |
| 115 rasterizer = VkPipelineRasterizationStateCreateInfo( | |
| 116 sType: VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, | |
| 117 depthClampEnable: VK_FALSE, | |
| 118 rasterizerDiscardEnable: VK_FALSE, | |
| 119 polygonMode: VK_POLYGON_MODE_FILL, | |
| 120 lineWidth: 1.0, | |
| 121 cullMode: if backFaceCulling: toBits [VK_CULL_MODE_BACK_BIT] else: VkCullModeFlags(0), | |
| 122 frontFace: VK_FRONT_FACE_CLOCKWISE, | |
| 123 depthBiasEnable: VK_FALSE, | |
| 124 depthBiasConstantFactor: 0.0, | |
| 125 depthBiasClamp: 0.0, | |
| 126 depthBiasSlopeFactor: 0.0, | |
| 127 ) | |
| 128 multisampling = VkPipelineMultisampleStateCreateInfo( | |
| 129 sType: VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, | |
| 130 sampleShadingEnable: VK_FALSE, | |
| 131 rasterizationSamples: samples, | |
| 132 minSampleShading: 1.0, | |
| 133 pSampleMask: nil, | |
| 134 alphaToCoverageEnable: VK_FALSE, | |
| 135 alphaToOneEnable: VK_FALSE, | |
| 136 ) | |
| 137 colorBlendAttachment = VkPipelineColorBlendAttachmentState( | |
| 138 colorWriteMask: toBits [VK_COLOR_COMPONENT_R_BIT, VK_COLOR_COMPONENT_G_BIT, VK_COLOR_COMPONENT_B_BIT, VK_COLOR_COMPONENT_A_BIT], | |
| 139 blendEnable: VK_TRUE, | |
| 140 srcColorBlendFactor: VK_BLEND_FACTOR_SRC_ALPHA, | |
| 141 dstColorBlendFactor: VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, | |
| 142 colorBlendOp: VK_BLEND_OP_ADD, | |
| 143 srcAlphaBlendFactor: VK_BLEND_FACTOR_ONE, | |
| 144 dstAlphaBlendFactor: VK_BLEND_FACTOR_ZERO, | |
| 145 alphaBlendOp: VK_BLEND_OP_ADD, | |
| 146 ) | |
| 147 colorBlending = VkPipelineColorBlendStateCreateInfo( | |
| 148 sType: VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, | |
| 149 logicOpEnable: false, | |
| 150 attachmentCount: 1, | |
| 151 pAttachments: addr(colorBlendAttachment), | |
| 152 ) | |
| 153 dynamicStates = @[VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR] | |
| 154 dynamicState = VkPipelineDynamicStateCreateInfo( | |
| 155 sType: VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, | |
| 156 dynamicStateCount: uint32(dynamicStates.len), | |
| 157 pDynamicStates: dynamicStates.ToCPointer, | |
| 158 ) | |
| 159 stages = @[result.shaderModules[0].GetPipelineInfo(), result.shaderModules[1].GetPipelineInfo()] | |
| 160 createInfo = VkGraphicsPipelineCreateInfo( | |
| 161 sType: VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, | |
| 162 stageCount: uint32(stages.len), | |
| 163 pStages: stages.ToCPointer, | |
| 164 pVertexInputState: addr(vertexInputInfo), | |
| 165 pInputAssemblyState: addr(inputAssembly), | |
| 166 pViewportState: addr(viewportState), | |
| 167 pRasterizationState: addr(rasterizer), | |
| 168 pMultisampleState: addr(multisampling), | |
| 169 pDepthStencilState: nil, | |
| 170 pColorBlendState: addr(colorBlending), | |
| 171 pDynamicState: addr(dynamicState), | |
| 172 layout: result.layout, | |
| 173 renderPass: renderPass, | |
| 174 subpass: subpass, | |
| 175 basePipelineHandle: VkPipeline(0), | |
| 176 basePipelineIndex: -1, | |
| 177 ) | |
| 178 checkVkResult vkCreateGraphicsPipelines( | |
| 179 device.vk, | |
| 180 VkPipelineCache(0), | |
| 181 1, | |
| 182 addr(createInfo), | |
| 183 nil, | |
| 184 addr(result.vk) | |
| 185 ) | |
| 186 | |
| 187 discard result.Uniforms # just for assertion | |
| 188 | |
| 189 | |
| 190 proc Destroy*(pipeline: var ShaderPipeline) = | |
| 191 assert pipeline.device.vk.Valid | |
| 192 assert pipeline.vk.Valid | |
| 193 assert pipeline.layout.Valid | |
| 194 assert pipeline.descriptorSetLayout.vk.Valid | |
| 195 | |
| 196 pipeline.shaderModules[0].Destroy() | |
| 197 pipeline.shaderModules[1].Destroy() | |
| 198 pipeline.descriptorSetLayout.Destroy() | |
| 199 pipeline.device.vk.vkDestroyPipelineLayout(pipeline.layout, nil) | |
| 200 pipeline.device.vk.vkDestroyPipeline(pipeline.vk, nil) | |
| 201 pipeline.descriptorSetLayout.vk.Reset() | |
| 202 pipeline.layout.Reset() | |
| 203 pipeline.vk.Reset() |
