Mercurial > games > semicongine
annotate src/zamikongine/shader.nim @ 500:8025ab67d931
fix: hello cube, add: run_all command
author | Sam <sam@basx.dev> |
---|---|
date | Wed, 18 Jan 2023 13:49:12 +0700 |
parents | 3f1111f3b9f8 |
children |
rev | line source |
---|---|
499
3f1111f3b9f8
did: tons of stuff, input, refactoring, fix some errors, some template improvment, sorry for super-commit
Sam <sam@basx.dev>
parents:
494
diff
changeset
|
1 import std/os |
3f1111f3b9f8
did: tons of stuff, input, refactoring, fix some errors, some template improvment, sorry for super-commit
Sam <sam@basx.dev>
parents:
494
diff
changeset
|
2 import std/hashes |
483
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
3 import std/strformat |
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
4 import std/strutils |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
5 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
|
6 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
|
7 |
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
8 import ./vulkan_helpers |
493 | 9 import ./glsl_helpers |
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
10 import ./vulkan |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
11 import ./vertex |
493 | 12 import ./descriptor |
489 | 13 import ./math/vector |
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
14 |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
15 type |
489 | 16 AllowedUniformType = SomeNumber|Vec |
17 UniformSlot *[T:AllowedUniformType] = object | |
493 | 18 ShaderProgram*[VertexType, Uniforms] = object |
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
19 entryPoint*: string |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
20 programType*: VkShaderStageFlagBits |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
21 shader*: VkPipelineShaderStageCreateInfo |
489 | 22 uniforms*: Uniforms |
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
23 |
485
b4a972bd37d5
did: change shader compilation to run during program compilation, maybe add dynamic version later
Sam <sam@basx.dev>
parents:
483
diff
changeset
|
24 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
|
25 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
|
26 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
|
27 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
|
28 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
|
29 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
|
30 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
|
31 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
|
32 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
|
33 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
|
34 |
499
3f1111f3b9f8
did: tons of stuff, input, refactoring, fix some errors, some template improvment, sorry for super-commit
Sam <sam@basx.dev>
parents:
494
diff
changeset
|
35 proc compileGLSLToSPIRV(stage: static VkShaderStageFlagBits, shaderSource: static string, entrypoint: string): seq[uint32] {.compileTime.} = |
3f1111f3b9f8
did: tons of stuff, input, refactoring, fix some errors, some template improvment, sorry for super-commit
Sam <sam@basx.dev>
parents:
494
diff
changeset
|
36 const |
3f1111f3b9f8
did: tons of stuff, input, refactoring, fix some errors, some template improvment, sorry for super-commit
Sam <sam@basx.dev>
parents:
494
diff
changeset
|
37 stagename = stage2string(stage) |
3f1111f3b9f8
did: tons of stuff, input, refactoring, fix some errors, some template improvment, sorry for super-commit
Sam <sam@basx.dev>
parents:
494
diff
changeset
|
38 shaderHash = hash(shaderSource) |
3f1111f3b9f8
did: tons of stuff, input, refactoring, fix some errors, some template improvment, sorry for super-commit
Sam <sam@basx.dev>
parents:
494
diff
changeset
|
39 # cross compilation for windows workaround, sorry computer |
3f1111f3b9f8
did: tons of stuff, input, refactoring, fix some errors, some template improvment, sorry for super-commit
Sam <sam@basx.dev>
parents:
494
diff
changeset
|
40 shaderout = getTempDir().replace("\\", "/") & "/" & fmt"shader_{shaderHash}.{stagename}" |
3f1111f3b9f8
did: tons of stuff, input, refactoring, fix some errors, some template improvment, sorry for super-commit
Sam <sam@basx.dev>
parents:
494
diff
changeset
|
41 projectPath = querySetting(projectPath) |
486
9231df12b222
fix: build from scratch not working, remove temp shader files from compilation
Sam <sam@basx.dev>
parents:
485
diff
changeset
|
42 |
499
3f1111f3b9f8
did: tons of stuff, input, refactoring, fix some errors, some template improvment, sorry for super-commit
Sam <sam@basx.dev>
parents:
494
diff
changeset
|
43 let (output, exitCode_glsl) = gorgeEx(command=fmt"{projectPath}/glslangValidator --entry-point {entrypoint} -V --stdin -S {stagename} -o {shaderout}", input=shaderSource) |
486
9231df12b222
fix: build from scratch not working, remove temp shader files from compilation
Sam <sam@basx.dev>
parents:
485
diff
changeset
|
44 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
|
45 raise newException(Exception, output) |
499
3f1111f3b9f8
did: tons of stuff, input, refactoring, fix some errors, some template improvment, sorry for super-commit
Sam <sam@basx.dev>
parents:
494
diff
changeset
|
46 if output == "": # this happens when the nim was invoked with "check" instead of "compile/c", as it prevents the gorgeEx command to really run. However, there is hope, see https://github.com/nim-lang/RFCs/issues/430 |
3f1111f3b9f8
did: tons of stuff, input, refactoring, fix some errors, some template improvment, sorry for super-commit
Sam <sam@basx.dev>
parents:
494
diff
changeset
|
47 return result |
3f1111f3b9f8
did: tons of stuff, input, refactoring, fix some errors, some template improvment, sorry for super-commit
Sam <sam@basx.dev>
parents:
494
diff
changeset
|
48 let shaderbinary = staticRead shaderout |
486
9231df12b222
fix: build from scratch not working, remove temp shader files from compilation
Sam <sam@basx.dev>
parents:
485
diff
changeset
|
49 |
499
3f1111f3b9f8
did: tons of stuff, input, refactoring, fix some errors, some template improvment, sorry for super-commit
Sam <sam@basx.dev>
parents:
494
diff
changeset
|
50 let (output_rm, exitCode_rm) = gorgeEx(command=fmt"rm {shaderout}") |
486
9231df12b222
fix: build from scratch not working, remove temp shader files from compilation
Sam <sam@basx.dev>
parents:
485
diff
changeset
|
51 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
|
52 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
|
53 |
483
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
54 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
|
55 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
|
56 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
|
57 (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
|
58 (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
|
59 (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
|
60 (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
|
61 ) |
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
62 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
|
63 |
493 | 64 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
|
65 result.entryPoint = entryPoint |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
66 result.programType = programType |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
67 |
485
b4a972bd37d5
did: change shader compilation to run during program compilation, maybe add dynamic version later
Sam <sam@basx.dev>
parents:
483
diff
changeset
|
68 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
|
69 var code = constcode |
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
70 var createInfo = VkShaderModuleCreateInfo( |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
71 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
|
72 codeSize: uint(code.len * sizeof(uint32)), |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
73 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
|
74 ) |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
75 var shaderModule: VkShaderModule |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
76 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
|
77 |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
78 result.shader = VkPipelineShaderStageCreateInfo( |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
79 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
|
80 stage: programType, |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
81 module: shaderModule, |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
82 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
|
83 ) |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
84 |
493 | 85 func generateVertexShaderCode*[VertexType, Uniforms]( |
86 shaderBody: static string = "", | |
87 entryPoint: static string = "main", | |
88 glslVersion: static string = "450" | |
89 ): string {.compileTime.} = | |
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
90 var lines: seq[string] |
493 | 91 lines.add "#version " & glslVersion |
92 lines.add "layout(row_major) uniform;" | |
93 lines.add generateGLSLUniformDeclarations[Uniforms]() | |
94 lines.add generateGLSLVertexDeclarations[VertexType]() | |
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
95 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
|
96 lines.add "void " & entryPoint & "() {" |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
97 |
493 | 98 var hasPosition = 0 |
99 var hasColor = 0 | |
489 | 100 for name, value in VertexType().fieldPairs: |
493 | 101 when typeof(value) is PositionAttribute: |
102 let glsltype = getGLSLType[getAttributeType(value)]() | |
103 lines.add &" {glsltype} in_position = " & name & ";" | |
104 if getAttributeType(value) is Vec2: | |
105 lines.add " vec4 out_position = vec4(in_position, 0.0, 1.0);" | |
106 elif getAttributeType(value) is Vec3: | |
107 lines.add " vec4 out_position = vec4(in_position, 1.0);" | |
108 elif getAttributeType(value) is Vec4: | |
109 lines.add " vec4 out_position = in_position;" | |
110 hasPosition += 1 | |
111 when typeof(value) is ColorAttribute: | |
112 let glsltype = getGLSLType[getAttributeType(value)]() | |
113 lines.add &" {glsltype} in_color = " & name & ";" | |
114 lines.add &" {glsltype} out_color = in_color;"; | |
115 hasColor += 1 | |
116 | |
117 lines.add shaderBody | |
118 lines.add " gl_Position = out_position;" | |
119 lines.add " fragColor = out_color;" | |
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
120 lines.add "}" |
493 | 121 if hasPosition != 1: |
122 raise newException(Exception, fmt"VertexType needs to have exactly one attribute of type PositionAttribute (has {hasPosition})") | |
123 if hasColor != 1: | |
124 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
|
125 return lines.join("\n") |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
126 |
493 | 127 func generateFragmentShaderCode*[VertexType]( |
128 shaderBody: static string = "", | |
129 entryPoint: static string = "main", | |
130 glslVersion: static string = "450" | |
131 ): string {.compileTime.} = | |
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
132 var lines: seq[string] |
493 | 133 lines.add "#version " & glslVersion |
134 lines.add "layout(row_major) uniform;" | |
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
135 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
|
136 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
|
137 lines.add "void " & entryPoint & "() {" |
493 | 138 lines.add " vec3 in_color = fragColor;" |
139 lines.add " vec3 out_color = in_color;" | |
140 lines.add shaderBody | |
141 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
|
142 lines.add "}" |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
143 |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
144 return lines.join("\n") |