Mercurial > games > semicongine
annotate src/zamikongine/shader.nim @ 485:b4a972bd37d5
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 | 73a0954beabd |
children | 9231df12b222 |
rev | line source |
---|---|
485
b4a972bd37d5
did: change shader compilation to run during program compilation, maybe add dynamic version later
Sam <sam@basx.dev>
parents:
483
diff
changeset
|
1 import std/tempfiles |
483
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
2 import std/strformat |
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
3 import std/strutils |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
4 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
|
5 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
|
6 |
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
7 |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
8 import ./vulkan_helpers |
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 |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
11 |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
12 type |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
13 ShaderProgram* = object |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
14 entryPoint*: string |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
15 programType*: VkShaderStageFlagBits |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
16 shader*: VkPipelineShaderStageCreateInfo |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
17 |
485
b4a972bd37d5
did: change shader compilation to run during program compilation, maybe add dynamic version later
Sam <sam@basx.dev>
parents:
483
diff
changeset
|
18 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
|
19 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
|
20 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
|
21 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
|
22 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
|
23 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
|
24 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
|
25 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
|
26 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
|
27 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
|
28 |
485
b4a972bd37d5
did: change shader compilation to run during program compilation, maybe add dynamic version later
Sam <sam@basx.dev>
parents:
483
diff
changeset
|
29 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
|
30 let stagename = stage2string(stage) |
485
b4a972bd37d5
did: change shader compilation to run during program compilation, maybe add dynamic version later
Sam <sam@basx.dev>
parents:
483
diff
changeset
|
31 let (tmpfile, tmpfilename) = createTempFile("shader", stage2string(stage)) |
b4a972bd37d5
did: change shader compilation to run during program compilation, maybe add dynamic version later
Sam <sam@basx.dev>
parents:
483
diff
changeset
|
32 tmpfile.close() |
b4a972bd37d5
did: change shader compilation to run during program compilation, maybe add dynamic version later
Sam <sam@basx.dev>
parents:
483
diff
changeset
|
33 let (output, exitCode) = gorgeEx(command=fmt"{querySetting(projectPath)}/glslangValidator --entry-point {entrypoint} -V --stdin -S {stagename} -o {tmpfilename}", input=shaderSource) |
483
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
34 if exitCode != 0: |
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
35 raise newException(Exception, output) |
485
b4a972bd37d5
did: change shader compilation to run during program compilation, maybe add dynamic version later
Sam <sam@basx.dev>
parents:
483
diff
changeset
|
36 let shaderbinary = staticRead tmpfilename |
483
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
37 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
|
38 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
|
39 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
|
40 (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
|
41 (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
|
42 (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
|
43 (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
|
44 ) |
73a0954beabd
did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents:
480
diff
changeset
|
45 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
|
46 |
485
b4a972bd37d5
did: change shader compilation to run during program compilation, maybe add dynamic version later
Sam <sam@basx.dev>
parents:
483
diff
changeset
|
47 proc initShaderProgram*(device: VkDevice, programType: static VkShaderStageFlagBits, shader: static string, entryPoint: static string="main"): ShaderProgram = |
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
48 result.entryPoint = entryPoint |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
49 result.programType = programType |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
50 |
485
b4a972bd37d5
did: change shader compilation to run during program compilation, maybe add dynamic version later
Sam <sam@basx.dev>
parents:
483
diff
changeset
|
51 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
|
52 var code = constcode |
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
53 var createInfo = VkShaderModuleCreateInfo( |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
54 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
|
55 codeSize: uint(code.len * sizeof(uint32)), |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
56 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
|
57 ) |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
58 var shaderModule: VkShaderModule |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
59 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
|
60 |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
61 result.shader = VkPipelineShaderStageCreateInfo( |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
62 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
|
63 stage: programType, |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
64 module: shaderModule, |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
65 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
|
66 ) |
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 func generateVertexShaderCode*[T](entryPoint, positionAttrName, colorAttrName: static string): string {.compileTime.} = |
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
69 var lines: seq[string] |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
70 lines.add "#version 450" |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
71 lines.add generateGLSLDeclarations[T]() |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
72 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
|
73 lines.add "void " & entryPoint & "() {" |
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 for name, value in T().fieldPairs: |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
76 when typeof(value) is VertexAttribute and name == positionAttrName: |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
77 lines.add " gl_Position = vec4(" & name & ", 0.0, 1.0);" |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
78 when typeof(value) is VertexAttribute and name == colorAttrName: |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
79 lines.add " fragColor = " & name & ";" |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
80 lines.add "}" |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
81 return lines.join("\n") |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
82 |
485
b4a972bd37d5
did: change shader compilation to run during program compilation, maybe add dynamic version later
Sam <sam@basx.dev>
parents:
483
diff
changeset
|
83 func generateFragmentShaderCode*[T](entryPoint: static string): string {.compileTime.} = |
480
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
84 var lines: seq[string] |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
85 lines.add "#version 450" |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
86 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
|
87 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
|
88 lines.add "void " & entryPoint & "() {" |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
89 lines.add " outColor = vec4(fragColor, 1.0);" |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
90 lines.add "}" |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
91 |
14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents:
diff
changeset
|
92 return lines.join("\n") |