Mercurial > games > semicongine
annotate src/zamikongine/shader.nim @ 494:0c18638c7217
did: refactoring, move more from make to nimscript
| author | Sam <sam@basx.dev> |
|---|---|
| date | Sun, 15 Jan 2023 23:23:54 +0700 |
| parents | 680c4b8ca28a |
| children | 3f1111f3b9f8 |
| rev | line source |
|---|---|
|
483
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
1 import std/strformat |
|
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
2 import std/strutils |
|
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
3 import std/tables |
|
485
b4a972bd37d5
did: change shader compilation to run during program compilation, maybe add dynamic version later
Sam <sam@basx.dev>
parents:
483
diff
changeset
|
4 import std/compilesettings |
|
b4a972bd37d5
did: change shader compilation to run during program compilation, maybe add dynamic version later
Sam <sam@basx.dev>
parents:
483
diff
changeset
|
5 |
|
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
6 |
|
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
7 import ./vulkan_helpers |
| 493 | 8 import ./glsl_helpers |
|
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
9 import ./vulkan |
|
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
10 import ./vertex |
| 493 | 11 import ./descriptor |
| 489 | 12 import ./math/vector |
|
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
13 |
|
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
14 type |
| 489 | 15 AllowedUniformType = SomeNumber|Vec |
| 16 UniformSlot *[T:AllowedUniformType] = object | |
| 493 | 17 ShaderProgram*[VertexType, Uniforms] = object |
|
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
18 entryPoint*: string |
|
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
19 programType*: VkShaderStageFlagBits |
|
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
20 shader*: VkPipelineShaderStageCreateInfo |
| 489 | 21 uniforms*: Uniforms |
|
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
22 |
|
485
b4a972bd37d5
did: change shader compilation to run during program compilation, maybe add dynamic version later
Sam <sam@basx.dev>
parents:
483
diff
changeset
|
23 func stage2string(stage: VkShaderStageFlagBits): string {.compileTime.} = |
|
483
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
24 case stage |
|
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
25 of VK_SHADER_STAGE_VERTEX_BIT: "vert" |
|
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
26 of VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: "tesc" |
|
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
27 of VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: "tese" |
|
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
28 of VK_SHADER_STAGE_GEOMETRY_BIT: "geom" |
|
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
29 of VK_SHADER_STAGE_FRAGMENT_BIT: "frag" |
|
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
30 of VK_SHADER_STAGE_ALL_GRAPHICS: "" |
|
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
31 of VK_SHADER_STAGE_COMPUTE_BIT: "comp" |
|
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
32 of VK_SHADER_STAGE_ALL: "" |
|
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
33 |
|
485
b4a972bd37d5
did: change shader compilation to run during program compilation, maybe add dynamic version later
Sam <sam@basx.dev>
parents:
483
diff
changeset
|
34 proc compileGLSLToSPIRV(stage: VkShaderStageFlagBits, shaderSource: string, entrypoint: string): seq[uint32] {.compileTime.} = |
|
483
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
35 let stagename = stage2string(stage) |
|
486
9231df12b222
fix: build from scratch not working, remove temp shader files from compilation
Sam <sam@basx.dev>
parents:
485
diff
changeset
|
36 |
| 489 | 37 # TODO: compiles only on linux for now (because we don't have compile-time functionality in std/tempfile) |
|
486
9231df12b222
fix: build from scratch not working, remove temp shader files from compilation
Sam <sam@basx.dev>
parents:
485
diff
changeset
|
38 let (tmpfile, exitCode) = gorgeEx(command=fmt"mktemp --tmpdir shader_XXXXXXX.{stagename}") |
|
483
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
39 if exitCode != 0: |
|
486
9231df12b222
fix: build from scratch not working, remove temp shader files from compilation
Sam <sam@basx.dev>
parents:
485
diff
changeset
|
40 raise newException(Exception, tmpfile) |
|
9231df12b222
fix: build from scratch not working, remove temp shader files from compilation
Sam <sam@basx.dev>
parents:
485
diff
changeset
|
41 |
|
9231df12b222
fix: build from scratch not working, remove temp shader files from compilation
Sam <sam@basx.dev>
parents:
485
diff
changeset
|
42 let (output, exitCode_glsl) = gorgeEx(command=fmt"{querySetting(projectPath)}/glslangValidator --entry-point {entrypoint} -V --stdin -S {stagename} -o {tmpfile}", input=shaderSource) |
|
9231df12b222
fix: build from scratch not working, remove temp shader files from compilation
Sam <sam@basx.dev>
parents:
485
diff
changeset
|
43 if exitCode_glsl != 0: |
|
483
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
44 raise newException(Exception, output) |
|
486
9231df12b222
fix: build from scratch not working, remove temp shader files from compilation
Sam <sam@basx.dev>
parents:
485
diff
changeset
|
45 let shaderbinary = staticRead tmpfile |
|
9231df12b222
fix: build from scratch not working, remove temp shader files from compilation
Sam <sam@basx.dev>
parents:
485
diff
changeset
|
46 |
|
9231df12b222
fix: build from scratch not working, remove temp shader files from compilation
Sam <sam@basx.dev>
parents:
485
diff
changeset
|
47 let (output_rm, exitCode_rm) = gorgeEx(command=fmt"rm {tmpfile}") |
|
9231df12b222
fix: build from scratch not working, remove temp shader files from compilation
Sam <sam@basx.dev>
parents:
485
diff
changeset
|
48 if exitCode_rm != 0: |
|
9231df12b222
fix: build from scratch not working, remove temp shader files from compilation
Sam <sam@basx.dev>
parents:
485
diff
changeset
|
49 raise newException(Exception, output_rm) |
|
9231df12b222
fix: build from scratch not working, remove temp shader files from compilation
Sam <sam@basx.dev>
parents:
485
diff
changeset
|
50 |
|
483
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
51 var i = 0 |
|
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
52 while i < shaderbinary.len: |
|
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
53 result.add( |
|
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
54 (uint32(shaderbinary[i + 0]) shl 0) or |
|
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
55 (uint32(shaderbinary[i + 1]) shl 8) or |
|
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
56 (uint32(shaderbinary[i + 2]) shl 16) or |
|
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
57 (uint32(shaderbinary[i + 3]) shl 24) |
|
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
58 ) |
|
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
59 i += 4 |
|
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
60 |
| 493 | 61 proc initShaderProgram*[VertexType, Uniforms](device: VkDevice, programType: static VkShaderStageFlagBits, shader: static string, entryPoint: static string="main"): ShaderProgram[VertexType, Uniforms] = |
|
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
62 result.entryPoint = entryPoint |
|
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
63 result.programType = programType |
|
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
64 |
|
485
b4a972bd37d5
did: change shader compilation to run during program compilation, maybe add dynamic version later
Sam <sam@basx.dev>
parents:
483
diff
changeset
|
65 const constcode = compileGLSLToSPIRV(programType, shader, entryPoint) |
|
b4a972bd37d5
did: change shader compilation to run during program compilation, maybe add dynamic version later
Sam <sam@basx.dev>
parents:
483
diff
changeset
|
66 var code = constcode |
|
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
67 var createInfo = VkShaderModuleCreateInfo( |
|
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
68 sType: VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, |
|
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
69 codeSize: uint(code.len * sizeof(uint32)), |
|
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
70 pCode: if code.len > 0: addr(code[0]) else: nil, |
|
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
71 ) |
|
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
72 var shaderModule: VkShaderModule |
|
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
73 checkVkResult vkCreateShaderModule(device, addr(createInfo), nil, addr(shaderModule)) |
|
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
74 |
|
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
75 result.shader = VkPipelineShaderStageCreateInfo( |
|
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
76 sType: VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, |
|
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
77 stage: programType, |
|
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
78 module: shaderModule, |
|
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
79 pName: cstring(result.entryPoint), # entry point for shader |
|
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
80 ) |
|
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
81 |
| 493 | 82 func generateVertexShaderCode*[VertexType, Uniforms]( |
| 83 shaderBody: static string = "", | |
| 84 entryPoint: static string = "main", | |
| 85 glslVersion: static string = "450" | |
| 86 ): string {.compileTime.} = | |
|
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
87 var lines: seq[string] |
| 493 | 88 lines.add "#version " & glslVersion |
| 89 lines.add "layout(row_major) uniform;" | |
| 90 lines.add generateGLSLUniformDeclarations[Uniforms]() | |
| 91 lines.add generateGLSLVertexDeclarations[VertexType]() | |
|
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
92 lines.add "layout(location = 0) out vec3 fragColor;" |
|
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
93 lines.add "void " & entryPoint & "() {" |
|
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
94 |
| 493 | 95 var hasPosition = 0 |
| 96 var hasColor = 0 | |
| 489 | 97 for name, value in VertexType().fieldPairs: |
| 493 | 98 when typeof(value) is PositionAttribute: |
| 99 let glsltype = getGLSLType[getAttributeType(value)]() | |
| 100 lines.add &" {glsltype} in_position = " & name & ";" | |
| 101 if getAttributeType(value) is Vec2: | |
| 102 lines.add " vec4 out_position = vec4(in_position, 0.0, 1.0);" | |
| 103 elif getAttributeType(value) is Vec3: | |
| 104 lines.add " vec4 out_position = vec4(in_position, 1.0);" | |
| 105 elif getAttributeType(value) is Vec4: | |
| 106 lines.add " vec4 out_position = in_position;" | |
| 107 hasPosition += 1 | |
| 108 when typeof(value) is ColorAttribute: | |
| 109 let glsltype = getGLSLType[getAttributeType(value)]() | |
| 110 lines.add &" {glsltype} in_color = " & name & ";" | |
| 111 lines.add &" {glsltype} out_color = in_color;"; | |
| 112 hasColor += 1 | |
| 113 | |
| 114 lines.add shaderBody | |
| 115 lines.add " gl_Position = out_position;" | |
| 116 lines.add " fragColor = out_color;" | |
|
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
117 lines.add "}" |
| 493 | 118 if hasPosition != 1: |
| 119 raise newException(Exception, fmt"VertexType needs to have exactly one attribute of type PositionAttribute (has {hasPosition})") | |
| 120 if hasColor != 1: | |
| 121 raise newException(Exception, fmt"VertexType needs to have exactly one attribute of type ColorAttribute (has {hasColor})") | |
|
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
122 return lines.join("\n") |
|
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
123 |
| 493 | 124 func generateFragmentShaderCode*[VertexType]( |
| 125 shaderBody: static string = "", | |
| 126 entryPoint: static string = "main", | |
| 127 glslVersion: static string = "450" | |
| 128 ): string {.compileTime.} = | |
|
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
129 var lines: seq[string] |
| 493 | 130 lines.add "#version " & glslVersion |
| 131 lines.add "layout(row_major) uniform;" | |
|
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
132 lines.add "layout(location = 0) in vec3 fragColor;" |
|
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
133 lines.add "layout(location = 0) out vec4 outColor;" |
|
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
134 lines.add "void " & entryPoint & "() {" |
| 493 | 135 lines.add " vec3 in_color = fragColor;" |
| 136 lines.add " vec3 out_color = in_color;" | |
| 137 lines.add shaderBody | |
| 138 lines.add " outColor = vec4(out_color, 1.0);" | |
|
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
139 lines.add "}" |
|
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
140 |
|
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
141 return lines.join("\n") |
