Mercurial > games > semicongine
comparison semiconginev2/rendering/shaders.nim @ 1252:01e9f41d35b1
add:support for push constants
author | sam <sam@basx.dev> |
---|---|
date | Fri, 26 Jul 2024 23:04:01 +0700 |
parents | c15770761865 |
children | c4f98eb4bb05 |
comparison
equal
deleted
inserted
replaced
1251:3f98ad20a9d3 | 1252:01e9f41d35b1 |
---|---|
129 var vsInput: seq[string] | 129 var vsInput: seq[string] |
130 var vsOutput: seq[string] | 130 var vsOutput: seq[string] |
131 var fsInput: seq[string] | 131 var fsInput: seq[string] |
132 var fsOutput: seq[string] | 132 var fsOutput: seq[string] |
133 var uniforms: seq[string] | 133 var uniforms: seq[string] |
134 var pushConstants: seq[string] | |
134 var samplers: seq[string] | 135 var samplers: seq[string] |
135 var vsInputLocation = 0'u32 | 136 var vsInputLocation = 0'u32 |
136 var passLocation = 0 | 137 var passLocation = 0 |
137 var fsOutputLocation = 0 | 138 var fsOutputLocation = 0 |
138 | 139 |
211 {.error: "Unsupported shader descriptor field " & descriptorName.} | 212 {.error: "Unsupported shader descriptor field " & descriptorName.} |
212 | 213 |
213 descriptorSetIndex.inc | 214 descriptorSetIndex.inc |
214 elif fieldname in ["vertexCode", "fragmentCode"]: | 215 elif fieldname in ["vertexCode", "fragmentCode"]: |
215 discard | 216 discard |
217 elif hasCustomPragma(value, PushConstantAttribute): | |
218 assert pushConstants.len == 0, "Only one push constant value allowed" | |
219 assert value is object, "push constants need to be objects" | |
220 pushConstants.add "layout( push_constant ) uniform constants" | |
221 pushConstants.add "{" | |
222 for constFieldName, constFieldValue in value.fieldPairs(): | |
223 assert typeof(constFieldValue) is SupportedGPUType, "push constant field '" & constFieldName & "' is not a SupportedGPUType" | |
224 pushConstants.add " " & GlslType(constFieldValue) & " " & constFieldName & ";" | |
225 pushConstants.add "} " & fieldname & ";" | |
216 else: | 226 else: |
217 {.error: "Unsupported shader field '" & typetraits.name(TShader) & "." & fieldname & "' of type " & typetraits.name(typeof(value)).} | 227 {.error: "Unsupported shader field '" & typetraits.name(TShader) & "." & fieldname & "' of type " & typetraits.name(typeof(value)).} |
218 | 228 |
219 result[0] = (@[&"#version {GLSL_VERSION}", "#extension GL_EXT_scalar_block_layout : require", ""] & | 229 result[0] = (@[&"#version {GLSL_VERSION}", "#extension GL_EXT_scalar_block_layout : require", ""] & |
220 vsInput & | 230 vsInput & |
221 uniforms & | 231 uniforms & |
232 pushConstants & | |
222 samplers & | 233 samplers & |
223 vsOutput & | 234 vsOutput & |
224 @[shader.vertexCode]).join("\n") | 235 @[shader.vertexCode]).join("\n") |
225 | 236 |
226 result[1] = (@[&"#version {GLSL_VERSION}", "#extension GL_EXT_scalar_block_layout : require", ""] & | 237 result[1] = (@[&"#version {GLSL_VERSION}", "#extension GL_EXT_scalar_block_layout : require", ""] & |
227 fsInput & | 238 fsInput & |
228 uniforms & | 239 uniforms & |
240 pushConstants & | |
229 samplers & | 241 samplers & |
230 fsOutput & | 242 fsOutput & |
231 @[shader.fragmentCode]).join("\n") | 243 @[shader.fragmentCode]).join("\n") |
232 | 244 |
233 proc compileGlslToSPIRV(stage: VkShaderStageFlagBits, shaderSource: string): seq[uint32] {.compileTime.} = | 245 proc compileGlslToSPIRV(stage: VkShaderStageFlagBits, shaderSource: string): seq[uint32] {.compileTime.} = |
358 const shader = default(TShader) | 370 const shader = default(TShader) |
359 (result.vertexShaderModule, result.fragmentShaderModule) = CompileShader(shader) | 371 (result.vertexShaderModule, result.fragmentShaderModule) = CompileShader(shader) |
360 | 372 |
361 var nSets = GetDescriptorSetCount[TShader]() | 373 var nSets = GetDescriptorSetCount[TShader]() |
362 result.descriptorSetLayouts = CreateDescriptorSetLayouts[TShader]() | 374 result.descriptorSetLayouts = CreateDescriptorSetLayouts[TShader]() |
375 | |
376 let pushConstant = VkPushConstantRange( | |
377 stageFlags: VkShaderStageFlags(VK_SHADER_STAGE_ALL_GRAPHICS), | |
378 offset: 0, | |
379 size: 128, # currently supported everywhere, places for two mat4 | |
380 ) | |
381 | |
363 let pipelineLayoutInfo = VkPipelineLayoutCreateInfo( | 382 let pipelineLayoutInfo = VkPipelineLayoutCreateInfo( |
364 sType: VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, | 383 sType: VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, |
365 setLayoutCount: nSets, | 384 setLayoutCount: nSets, |
366 pSetLayouts: if nSets == 0: nil else: result.descriptorSetLayouts.ToCPointer, | 385 pSetLayouts: if nSets == 0: nil else: result.descriptorSetLayouts.ToCPointer, |
367 # pushConstantRangeCount: uint32(pushConstants.len), | 386 pushConstantRangeCount: 1, |
368 # pPushConstantRanges: pushConstants.ToCPointer, | 387 pPushConstantRanges: addr(pushConstant), |
369 ) | 388 ) |
370 checkVkResult vkCreatePipelineLayout(vulkan.device, addr(pipelineLayoutInfo), nil, addr(result.layout)) | 389 checkVkResult vkCreatePipelineLayout(vulkan.device, addr(pipelineLayoutInfo), nil, addr(result.layout)) |
371 | 390 |
372 let stages = [ | 391 let stages = [ |
373 VkPipelineShaderStageCreateInfo( | 392 VkPipelineShaderStageCreateInfo( |