comparison 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
comparison
equal deleted inserted replaced
21:316923e9247c 22:b45a5d338cd0
1 import std/osproc
2 import std/strformat
1 import std/strutils 3 import std/strutils
2 import std/tables 4 import std/tables
3 5
4 import ./vulkan_helpers 6 import ./vulkan_helpers
5 import ./vulkan 7 import ./vulkan
6 import ./vertex 8 import ./vertex
7 import ./glslang/glslang
8 9
9 type 10 type
10 ShaderProgram* = object 11 ShaderProgram* = object
11 entryPoint*: string 12 entryPoint*: string
12 programType*: VkShaderStageFlagBits 13 programType*: VkShaderStageFlagBits
13 shader*: VkPipelineShaderStageCreateInfo 14 shader*: VkPipelineShaderStageCreateInfo
14 15
16 func stage2string(stage: VkShaderStageFlagBits): string =
17 case stage
18 of VK_SHADER_STAGE_VERTEX_BIT: "vert"
19 of VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: "tesc"
20 of VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: "tese"
21 of VK_SHADER_STAGE_GEOMETRY_BIT: "geom"
22 of VK_SHADER_STAGE_FRAGMENT_BIT: "frag"
23 of VK_SHADER_STAGE_ALL_GRAPHICS: ""
24 of VK_SHADER_STAGE_COMPUTE_BIT: "comp"
25 of VK_SHADER_STAGE_ALL: ""
26
27 proc compileGLSLToSPIRV(stage: VkShaderStageFlagBits, shaderSource: string, entrypoint: string): seq[uint32] =
28 let stagename = stage2string(stage)
29 let (output, exitCode) = execCmdEx(command=fmt"./glslangValidator --entry-point {entrypoint} -V --stdin -S {stagename}", input=shaderSource)
30 if exitCode != 0:
31 raise newException(Exception, output)
32 let shaderbinary = readFile fmt"{stagename}.spv"
33 var i = 0
34 while i < shaderbinary.len:
35 result.add(
36 (uint32(shaderbinary[i + 0]) shl 0) or
37 (uint32(shaderbinary[i + 1]) shl 8) or
38 (uint32(shaderbinary[i + 2]) shl 16) or
39 (uint32(shaderbinary[i + 3]) shl 24)
40 )
41 i += 4
42
15 proc initShaderProgram*(device: VkDevice, programType: VkShaderStageFlagBits, shader: string, entryPoint: string="main"): ShaderProgram = 43 proc initShaderProgram*(device: VkDevice, programType: VkShaderStageFlagBits, shader: string, entryPoint: string="main"): ShaderProgram =
16 result.entryPoint = entryPoint 44 result.entryPoint = entryPoint
17 result.programType = programType 45 result.programType = programType
18 46
19 const VK_GLSL_MAP = { 47 var code = compileGLSLToSPIRV(result.programType, shader, result.entryPoint)
20 VK_SHADER_STAGE_VERTEX_BIT: GLSLANG_STAGE_VERTEX,
21 VK_SHADER_STAGE_FRAGMENT_BIT: GLSLANG_STAGE_FRAGMENT,
22 }.toTable()
23 var code = compileGLSLToSPIRV(VK_GLSL_MAP[result.programType], shader, "<memory-shader>")
24 var createInfo = VkShaderModuleCreateInfo( 48 var createInfo = VkShaderModuleCreateInfo(
25 sType: VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, 49 sType: VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
26 codeSize: uint(code.len * sizeof(uint32)), 50 codeSize: uint(code.len * sizeof(uint32)),
27 pCode: if code.len > 0: addr(code[0]) else: nil, 51 pCode: if code.len > 0: addr(code[0]) else: nil,
28 ) 52 )