annotate src/zamikongine/shader.nim @ 22:b45a5d338cd0

did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
author Sam <sam@basx.dev>
date Wed, 11 Jan 2023 00:43:17 +0700
parents b55d6ecde79d
children 71bbe11d8de8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
22
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
1 import std/osproc
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
2 import std/strformat
19
b55d6ecde79d did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents: 17
diff changeset
3 import std/strutils
17
b40466fa446a add: vertex basics, some refactoring
Sam <sam@basx.dev>
parents:
diff changeset
4 import std/tables
b40466fa446a add: vertex basics, some refactoring
Sam <sam@basx.dev>
parents:
diff changeset
5
b40466fa446a add: vertex basics, some refactoring
Sam <sam@basx.dev>
parents:
diff changeset
6 import ./vulkan_helpers
b40466fa446a add: vertex basics, some refactoring
Sam <sam@basx.dev>
parents:
diff changeset
7 import ./vulkan
19
b55d6ecde79d did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents: 17
diff changeset
8 import ./vertex
17
b40466fa446a add: vertex basics, some refactoring
Sam <sam@basx.dev>
parents:
diff changeset
9
b40466fa446a add: vertex basics, some refactoring
Sam <sam@basx.dev>
parents:
diff changeset
10 type
b40466fa446a add: vertex basics, some refactoring
Sam <sam@basx.dev>
parents:
diff changeset
11 ShaderProgram* = object
b40466fa446a add: vertex basics, some refactoring
Sam <sam@basx.dev>
parents:
diff changeset
12 entryPoint*: string
b40466fa446a add: vertex basics, some refactoring
Sam <sam@basx.dev>
parents:
diff changeset
13 programType*: VkShaderStageFlagBits
b40466fa446a add: vertex basics, some refactoring
Sam <sam@basx.dev>
parents:
diff changeset
14 shader*: VkPipelineShaderStageCreateInfo
b40466fa446a add: vertex basics, some refactoring
Sam <sam@basx.dev>
parents:
diff changeset
15
22
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
16 func stage2string(stage: VkShaderStageFlagBits): string =
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
17 case stage
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
18 of VK_SHADER_STAGE_VERTEX_BIT: "vert"
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
19 of VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: "tesc"
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
20 of VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: "tese"
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
21 of VK_SHADER_STAGE_GEOMETRY_BIT: "geom"
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
22 of VK_SHADER_STAGE_FRAGMENT_BIT: "frag"
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
23 of VK_SHADER_STAGE_ALL_GRAPHICS: ""
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
24 of VK_SHADER_STAGE_COMPUTE_BIT: "comp"
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
25 of VK_SHADER_STAGE_ALL: ""
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
26
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
27 proc compileGLSLToSPIRV(stage: VkShaderStageFlagBits, shaderSource: string, entrypoint: string): seq[uint32] =
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
28 let stagename = stage2string(stage)
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
29 let (output, exitCode) = execCmdEx(command=fmt"./glslangValidator --entry-point {entrypoint} -V --stdin -S {stagename}", input=shaderSource)
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
30 if exitCode != 0:
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
31 raise newException(Exception, output)
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
32 let shaderbinary = readFile fmt"{stagename}.spv"
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
33 var i = 0
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
34 while i < shaderbinary.len:
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
35 result.add(
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
36 (uint32(shaderbinary[i + 0]) shl 0) or
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
37 (uint32(shaderbinary[i + 1]) shl 8) or
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
38 (uint32(shaderbinary[i + 2]) shl 16) or
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
39 (uint32(shaderbinary[i + 3]) shl 24)
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
40 )
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
41 i += 4
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
42
17
b40466fa446a add: vertex basics, some refactoring
Sam <sam@basx.dev>
parents:
diff changeset
43 proc initShaderProgram*(device: VkDevice, programType: VkShaderStageFlagBits, shader: string, entryPoint: string="main"): ShaderProgram =
b40466fa446a add: vertex basics, some refactoring
Sam <sam@basx.dev>
parents:
diff changeset
44 result.entryPoint = entryPoint
b40466fa446a add: vertex basics, some refactoring
Sam <sam@basx.dev>
parents:
diff changeset
45 result.programType = programType
b40466fa446a add: vertex basics, some refactoring
Sam <sam@basx.dev>
parents:
diff changeset
46
22
b45a5d338cd0 did: improve alotof_triangles example, remove glslang lib, use only binary, easier cross-compilation
Sam <sam@basx.dev>
parents: 19
diff changeset
47 var code = compileGLSLToSPIRV(result.programType, shader, result.entryPoint)
17
b40466fa446a add: vertex basics, some refactoring
Sam <sam@basx.dev>
parents:
diff changeset
48 var createInfo = VkShaderModuleCreateInfo(
b40466fa446a add: vertex basics, some refactoring
Sam <sam@basx.dev>
parents:
diff changeset
49 sType: VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
b40466fa446a add: vertex basics, some refactoring
Sam <sam@basx.dev>
parents:
diff changeset
50 codeSize: uint(code.len * sizeof(uint32)),
b40466fa446a add: vertex basics, some refactoring
Sam <sam@basx.dev>
parents:
diff changeset
51 pCode: if code.len > 0: addr(code[0]) else: nil,
b40466fa446a add: vertex basics, some refactoring
Sam <sam@basx.dev>
parents:
diff changeset
52 )
b40466fa446a add: vertex basics, some refactoring
Sam <sam@basx.dev>
parents:
diff changeset
53 var shaderModule: VkShaderModule
b40466fa446a add: vertex basics, some refactoring
Sam <sam@basx.dev>
parents:
diff changeset
54 checkVkResult vkCreateShaderModule(device, addr(createInfo), nil, addr(shaderModule))
b40466fa446a add: vertex basics, some refactoring
Sam <sam@basx.dev>
parents:
diff changeset
55
b40466fa446a add: vertex basics, some refactoring
Sam <sam@basx.dev>
parents:
diff changeset
56 result.shader = VkPipelineShaderStageCreateInfo(
b40466fa446a add: vertex basics, some refactoring
Sam <sam@basx.dev>
parents:
diff changeset
57 sType: VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
b40466fa446a add: vertex basics, some refactoring
Sam <sam@basx.dev>
parents:
diff changeset
58 stage: programType,
b40466fa446a add: vertex basics, some refactoring
Sam <sam@basx.dev>
parents:
diff changeset
59 module: shaderModule,
b40466fa446a add: vertex basics, some refactoring
Sam <sam@basx.dev>
parents:
diff changeset
60 pName: cstring(result.entryPoint), # entry point for shader
b40466fa446a add: vertex basics, some refactoring
Sam <sam@basx.dev>
parents:
diff changeset
61 )
19
b55d6ecde79d did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents: 17
diff changeset
62
b55d6ecde79d did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents: 17
diff changeset
63 func generateVertexShaderCode*[T](entryPoint, positionAttrName, colorAttrName: static string): string =
b55d6ecde79d did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents: 17
diff changeset
64 var lines: seq[string]
b55d6ecde79d did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents: 17
diff changeset
65 lines.add "#version 450"
b55d6ecde79d did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents: 17
diff changeset
66 lines.add generateGLSLDeclarations[T]()
b55d6ecde79d did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents: 17
diff changeset
67 lines.add "layout(location = 0) out vec3 fragColor;"
b55d6ecde79d did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents: 17
diff changeset
68 lines.add "void " & entryPoint & "() {"
b55d6ecde79d did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents: 17
diff changeset
69
b55d6ecde79d did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents: 17
diff changeset
70 for name, value in T().fieldPairs:
b55d6ecde79d did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents: 17
diff changeset
71 when typeof(value) is VertexAttribute and name == positionAttrName:
b55d6ecde79d did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents: 17
diff changeset
72 lines.add " gl_Position = vec4(" & name & ", 0.0, 1.0);"
b55d6ecde79d did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents: 17
diff changeset
73 when typeof(value) is VertexAttribute and name == colorAttrName:
b55d6ecde79d did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents: 17
diff changeset
74 lines.add " fragColor = " & name & ";"
b55d6ecde79d did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents: 17
diff changeset
75 lines.add "}"
b55d6ecde79d did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents: 17
diff changeset
76 return lines.join("\n")
b55d6ecde79d did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents: 17
diff changeset
77
b55d6ecde79d did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents: 17
diff changeset
78 func generateFragmentShaderCode*[T](entryPoint: static string): string =
b55d6ecde79d did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents: 17
diff changeset
79 var lines: seq[string]
b55d6ecde79d did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents: 17
diff changeset
80 lines.add "#version 450"
b55d6ecde79d did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents: 17
diff changeset
81 lines.add "layout(location = 0) in vec3 fragColor;"
b55d6ecde79d did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents: 17
diff changeset
82 lines.add "layout(location = 0) out vec4 outColor;"
b55d6ecde79d did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents: 17
diff changeset
83 lines.add "void " & entryPoint & "() {"
b55d6ecde79d did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents: 17
diff changeset
84 lines.add " outColor = vec4(fragColor, 1.0);"
b55d6ecde79d did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents: 17
diff changeset
85 lines.add "}"
b55d6ecde79d did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents: 17
diff changeset
86
b55d6ecde79d did: introduce scene graph, meshs and generic vertex buffers
Sam <sam@basx.dev>
parents: 17
diff changeset
87 return lines.join("\n")