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