Mercurial > games > semicongine
comparison src/zamikongine/shader.nim @ 28:b1b05d4efb52
big refactoring, part1
| author | Sam <sam@basx.dev> |
|---|---|
| date | Sat, 14 Jan 2023 14:08:00 +0700 |
| parents | 8f290112718a |
| children | 9edca5dc4e93 |
comparison
equal
deleted
inserted
replaced
| 27:8cb2d96ac28e | 28:b1b05d4efb52 |
|---|---|
| 5 | 5 |
| 6 | 6 |
| 7 import ./vulkan_helpers | 7 import ./vulkan_helpers |
| 8 import ./vulkan | 8 import ./vulkan |
| 9 import ./vertex | 9 import ./vertex |
| 10 import ./math/vector | |
| 10 | 11 |
| 11 type | 12 type |
| 12 ShaderProgram* = object | 13 AllowedUniformType = SomeNumber|Vec |
| 14 UniformSlot *[T:AllowedUniformType] = object | |
| 15 ShaderProgram*[Uniforms] = object | |
| 13 entryPoint*: string | 16 entryPoint*: string |
| 14 programType*: VkShaderStageFlagBits | 17 programType*: VkShaderStageFlagBits |
| 15 shader*: VkPipelineShaderStageCreateInfo | 18 shader*: VkPipelineShaderStageCreateInfo |
| 19 uniforms*: Uniforms | |
| 16 | 20 |
| 17 func stage2string(stage: VkShaderStageFlagBits): string {.compileTime.} = | 21 func stage2string(stage: VkShaderStageFlagBits): string {.compileTime.} = |
| 18 case stage | 22 case stage |
| 19 of VK_SHADER_STAGE_VERTEX_BIT: "vert" | 23 of VK_SHADER_STAGE_VERTEX_BIT: "vert" |
| 20 of VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: "tesc" | 24 of VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: "tesc" |
| 24 of VK_SHADER_STAGE_ALL_GRAPHICS: "" | 28 of VK_SHADER_STAGE_ALL_GRAPHICS: "" |
| 25 of VK_SHADER_STAGE_COMPUTE_BIT: "comp" | 29 of VK_SHADER_STAGE_COMPUTE_BIT: "comp" |
| 26 of VK_SHADER_STAGE_ALL: "" | 30 of VK_SHADER_STAGE_ALL: "" |
| 27 | 31 |
| 28 proc compileGLSLToSPIRV(stage: VkShaderStageFlagBits, shaderSource: string, entrypoint: string): seq[uint32] {.compileTime.} = | 32 proc compileGLSLToSPIRV(stage: VkShaderStageFlagBits, shaderSource: string, entrypoint: string): seq[uint32] {.compileTime.} = |
| 29 # TODO: compiles only on linux for now (because we don't have compile-time functionality in std/tempfile) | |
| 30 let stagename = stage2string(stage) | 33 let stagename = stage2string(stage) |
| 31 | 34 |
| 35 # TODO: compiles only on linux for now (because we don't have compile-time functionality in std/tempfile) | |
| 36 if not defined(linux): | |
| 37 raise newException(Exception, "Compilation is currently only supported on linux (need mktemp command), sorry!") | |
| 32 let (tmpfile, exitCode) = gorgeEx(command=fmt"mktemp --tmpdir shader_XXXXXXX.{stagename}") | 38 let (tmpfile, exitCode) = gorgeEx(command=fmt"mktemp --tmpdir shader_XXXXXXX.{stagename}") |
| 33 if exitCode != 0: | 39 if exitCode != 0: |
| 34 raise newException(Exception, tmpfile) | 40 raise newException(Exception, tmpfile) |
| 35 | 41 |
| 36 let (output, exitCode_glsl) = gorgeEx(command=fmt"{querySetting(projectPath)}/glslangValidator --entry-point {entrypoint} -V --stdin -S {stagename} -o {tmpfile}", input=shaderSource) | 42 let (output, exitCode_glsl) = gorgeEx(command=fmt"{querySetting(projectPath)}/glslangValidator --entry-point {entrypoint} -V --stdin -S {stagename} -o {tmpfile}", input=shaderSource) |
| 50 (uint32(shaderbinary[i + 2]) shl 16) or | 56 (uint32(shaderbinary[i + 2]) shl 16) or |
| 51 (uint32(shaderbinary[i + 3]) shl 24) | 57 (uint32(shaderbinary[i + 3]) shl 24) |
| 52 ) | 58 ) |
| 53 i += 4 | 59 i += 4 |
| 54 | 60 |
| 55 proc initShaderProgram*(device: VkDevice, programType: static VkShaderStageFlagBits, shader: static string, entryPoint: static string="main"): ShaderProgram = | 61 proc initShaderProgram*[T](device: VkDevice, programType: static VkShaderStageFlagBits, shader: static string, entryPoint: static string="main"): ShaderProgram[T] = |
| 56 result.entryPoint = entryPoint | 62 result.entryPoint = entryPoint |
| 57 result.programType = programType | 63 result.programType = programType |
| 58 | 64 |
| 59 const constcode = compileGLSLToSPIRV(programType, shader, entryPoint) | 65 const constcode = compileGLSLToSPIRV(programType, shader, entryPoint) |
| 60 var code = constcode | 66 var code = constcode |
| 71 stage: programType, | 77 stage: programType, |
| 72 module: shaderModule, | 78 module: shaderModule, |
| 73 pName: cstring(result.entryPoint), # entry point for shader | 79 pName: cstring(result.entryPoint), # entry point for shader |
| 74 ) | 80 ) |
| 75 | 81 |
| 76 func generateVertexShaderCode*[T](entryPoint, positionAttrName, colorAttrName: static string): string {.compileTime.} = | 82 func generateVertexShaderCode*[VertexType](entryPoint, positionAttrName, colorAttrName: static string): string {.compileTime.} = |
| 77 var lines: seq[string] | 83 var lines: seq[string] |
| 78 lines.add "#version 450" | 84 lines.add "#version 450" |
| 79 lines.add generateGLSLDeclarations[T]() | 85 # lines.add "layout(binding = 0) uniform UniformBufferObject { float dt; } ubo;" |
| 86 lines.add generateGLSLDeclarations[VertexType]() | |
| 80 lines.add "layout(location = 0) out vec3 fragColor;" | 87 lines.add "layout(location = 0) out vec3 fragColor;" |
| 81 lines.add "void " & entryPoint & "() {" | 88 lines.add "void " & entryPoint & "() {" |
| 82 | 89 |
| 83 for name, value in T().fieldPairs: | 90 for name, value in VertexType().fieldPairs: |
| 84 when typeof(value) is VertexAttribute and name == positionAttrName: | 91 when typeof(value) is VertexAttribute and name == positionAttrName: |
| 85 lines.add " gl_Position = vec4(" & name & ", 0.0, 1.0);" | 92 # lines.add " vec2 tmp = " & name & " * ubo.dt;" |
| 93 lines.add " vec2 tmp = " & name & ";" | |
| 94 lines.add " gl_Position = vec4(tmp, 0.0, 1.0);" | |
| 86 when typeof(value) is VertexAttribute and name == colorAttrName: | 95 when typeof(value) is VertexAttribute and name == colorAttrName: |
| 87 lines.add " fragColor = " & name & ";" | 96 lines.add " fragColor = " & name & ";" |
| 88 lines.add "}" | 97 lines.add "}" |
| 89 return lines.join("\n") | 98 return lines.join("\n") |
| 90 | 99 |
| 91 func generateFragmentShaderCode*[T](entryPoint: static string): string {.compileTime.} = | 100 func generateFragmentShaderCode*[VertexType](entryPoint: static string): string {.compileTime.} = |
| 92 var lines: seq[string] | 101 var lines: seq[string] |
| 93 lines.add "#version 450" | 102 lines.add "#version 450" |
| 94 lines.add "layout(location = 0) in vec3 fragColor;" | 103 lines.add "layout(location = 0) in vec3 fragColor;" |
| 95 lines.add "layout(location = 0) out vec4 outColor;" | 104 lines.add "layout(location = 0) out vec4 outColor;" |
| 96 lines.add "void " & entryPoint & "() {" | 105 lines.add "void " & entryPoint & "() {" |
