Mercurial > games > semicongine
comparison src/zamikongine/shader.nim @ 24:71bbe11d8de8
did: change shader compilation to run during program compilation, maybe add dynamic version later
author | Sam <sam@basx.dev> |
---|---|
date | Wed, 11 Jan 2023 11:15:02 +0700 |
parents | b45a5d338cd0 |
children | 8f290112718a |
comparison
equal
deleted
inserted
replaced
23:0ffdf1f4ecf4 | 24:71bbe11d8de8 |
---|---|
1 import std/osproc | 1 import std/tempfiles |
2 import std/strformat | 2 import std/strformat |
3 import std/strutils | 3 import std/strutils |
4 import std/tables | 4 import std/tables |
5 import std/compilesettings | |
6 | |
5 | 7 |
6 import ./vulkan_helpers | 8 import ./vulkan_helpers |
7 import ./vulkan | 9 import ./vulkan |
8 import ./vertex | 10 import ./vertex |
9 | 11 |
11 ShaderProgram* = object | 13 ShaderProgram* = object |
12 entryPoint*: string | 14 entryPoint*: string |
13 programType*: VkShaderStageFlagBits | 15 programType*: VkShaderStageFlagBits |
14 shader*: VkPipelineShaderStageCreateInfo | 16 shader*: VkPipelineShaderStageCreateInfo |
15 | 17 |
16 func stage2string(stage: VkShaderStageFlagBits): string = | 18 func stage2string(stage: VkShaderStageFlagBits): string {.compileTime.} = |
17 case stage | 19 case stage |
18 of VK_SHADER_STAGE_VERTEX_BIT: "vert" | 20 of VK_SHADER_STAGE_VERTEX_BIT: "vert" |
19 of VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: "tesc" | 21 of VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: "tesc" |
20 of VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: "tese" | 22 of VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: "tese" |
21 of VK_SHADER_STAGE_GEOMETRY_BIT: "geom" | 23 of VK_SHADER_STAGE_GEOMETRY_BIT: "geom" |
22 of VK_SHADER_STAGE_FRAGMENT_BIT: "frag" | 24 of VK_SHADER_STAGE_FRAGMENT_BIT: "frag" |
23 of VK_SHADER_STAGE_ALL_GRAPHICS: "" | 25 of VK_SHADER_STAGE_ALL_GRAPHICS: "" |
24 of VK_SHADER_STAGE_COMPUTE_BIT: "comp" | 26 of VK_SHADER_STAGE_COMPUTE_BIT: "comp" |
25 of VK_SHADER_STAGE_ALL: "" | 27 of VK_SHADER_STAGE_ALL: "" |
26 | 28 |
27 proc compileGLSLToSPIRV(stage: VkShaderStageFlagBits, shaderSource: string, entrypoint: string): seq[uint32] = | 29 proc compileGLSLToSPIRV(stage: VkShaderStageFlagBits, shaderSource: string, entrypoint: string): seq[uint32] {.compileTime.} = |
28 let stagename = stage2string(stage) | 30 let stagename = stage2string(stage) |
29 let (output, exitCode) = execCmdEx(command=fmt"./glslangValidator --entry-point {entrypoint} -V --stdin -S {stagename}", input=shaderSource) | 31 let (tmpfile, tmpfilename) = createTempFile("shader", stage2string(stage)) |
32 tmpfile.close() | |
33 let (output, exitCode) = gorgeEx(command=fmt"{querySetting(projectPath)}/glslangValidator --entry-point {entrypoint} -V --stdin -S {stagename} -o {tmpfilename}", input=shaderSource) | |
30 if exitCode != 0: | 34 if exitCode != 0: |
31 raise newException(Exception, output) | 35 raise newException(Exception, output) |
32 let shaderbinary = readFile fmt"{stagename}.spv" | 36 let shaderbinary = staticRead tmpfilename |
33 var i = 0 | 37 var i = 0 |
34 while i < shaderbinary.len: | 38 while i < shaderbinary.len: |
35 result.add( | 39 result.add( |
36 (uint32(shaderbinary[i + 0]) shl 0) or | 40 (uint32(shaderbinary[i + 0]) shl 0) or |
37 (uint32(shaderbinary[i + 1]) shl 8) or | 41 (uint32(shaderbinary[i + 1]) shl 8) or |
38 (uint32(shaderbinary[i + 2]) shl 16) or | 42 (uint32(shaderbinary[i + 2]) shl 16) or |
39 (uint32(shaderbinary[i + 3]) shl 24) | 43 (uint32(shaderbinary[i + 3]) shl 24) |
40 ) | 44 ) |
41 i += 4 | 45 i += 4 |
42 | 46 |
43 proc initShaderProgram*(device: VkDevice, programType: VkShaderStageFlagBits, shader: string, entryPoint: string="main"): ShaderProgram = | 47 proc initShaderProgram*(device: VkDevice, programType: static VkShaderStageFlagBits, shader: static string, entryPoint: static string="main"): ShaderProgram = |
44 result.entryPoint = entryPoint | 48 result.entryPoint = entryPoint |
45 result.programType = programType | 49 result.programType = programType |
46 | 50 |
47 var code = compileGLSLToSPIRV(result.programType, shader, result.entryPoint) | 51 const constcode = compileGLSLToSPIRV(programType, shader, entryPoint) |
52 var code = constcode | |
48 var createInfo = VkShaderModuleCreateInfo( | 53 var createInfo = VkShaderModuleCreateInfo( |
49 sType: VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, | 54 sType: VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, |
50 codeSize: uint(code.len * sizeof(uint32)), | 55 codeSize: uint(code.len * sizeof(uint32)), |
51 pCode: if code.len > 0: addr(code[0]) else: nil, | 56 pCode: if code.len > 0: addr(code[0]) else: nil, |
52 ) | 57 ) |
58 stage: programType, | 63 stage: programType, |
59 module: shaderModule, | 64 module: shaderModule, |
60 pName: cstring(result.entryPoint), # entry point for shader | 65 pName: cstring(result.entryPoint), # entry point for shader |
61 ) | 66 ) |
62 | 67 |
63 func generateVertexShaderCode*[T](entryPoint, positionAttrName, colorAttrName: static string): string = | 68 func generateVertexShaderCode*[T](entryPoint, positionAttrName, colorAttrName: static string): string {.compileTime.} = |
64 var lines: seq[string] | 69 var lines: seq[string] |
65 lines.add "#version 450" | 70 lines.add "#version 450" |
66 lines.add generateGLSLDeclarations[T]() | 71 lines.add generateGLSLDeclarations[T]() |
67 lines.add "layout(location = 0) out vec3 fragColor;" | 72 lines.add "layout(location = 0) out vec3 fragColor;" |
68 lines.add "void " & entryPoint & "() {" | 73 lines.add "void " & entryPoint & "() {" |
73 when typeof(value) is VertexAttribute and name == colorAttrName: | 78 when typeof(value) is VertexAttribute and name == colorAttrName: |
74 lines.add " fragColor = " & name & ";" | 79 lines.add " fragColor = " & name & ";" |
75 lines.add "}" | 80 lines.add "}" |
76 return lines.join("\n") | 81 return lines.join("\n") |
77 | 82 |
78 func generateFragmentShaderCode*[T](entryPoint: static string): string = | 83 func generateFragmentShaderCode*[T](entryPoint: static string): string {.compileTime.} = |
79 var lines: seq[string] | 84 var lines: seq[string] |
80 lines.add "#version 450" | 85 lines.add "#version 450" |
81 lines.add "layout(location = 0) in vec3 fragColor;" | 86 lines.add "layout(location = 0) in vec3 fragColor;" |
82 lines.add "layout(location = 0) out vec4 outColor;" | 87 lines.add "layout(location = 0) out vec4 outColor;" |
83 lines.add "void " & entryPoint & "() {" | 88 lines.add "void " & entryPoint & "() {" |