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 & "() {" |