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() |