Compile SPIR-V shaders

Vulkan requires shaders to be in SPIR-V form. We will showcase how to compile shaders into SPIR-V using glslang from Julia.

Let's first define a GLSL shader:

shader_code = """
#version 450

layout(location = 0) in vec2 pos;
layout(location = 0) out vec4 color;

void main() {
    color = vec4(pos, 0.0, 1.0);
}
""";

We will use glslang to compile this code into a SPIR-V binary file. First, get the path to the binary.

using glslang_jll: glslangValidator
glslang = glslangValidator(identity)
"/home/runner/.julia/artifacts/f1fa93f41410326ba4ca250dbf71306ccc966830/bin/glslangValidator"

Fill in an IOBuffer with the shader code (to be used as standard input).

_stdin = IOBuffer()
write(_stdin, shader_code)
seekstart(_stdin)
flags = ["--stdin"]
1-element Vector{String}:
 "--stdin"

Specify which kind of shader we are compiling. Here, we have Vulkan-flavored GLSL, and we will indicate that it is a vertex shader. If your shader is written in HLSL instead of GLSL, you should also provide an additional "-D" flag.

push!(flags, "-V", "-S", "vert");

Use a temporary file as output, as glslang does not yet support outputting code to stdout.

path = tempname()
push!(flags, "-o", path)
6-element Vector{String}:
 "--stdin"
 "-V"
 "-S"
 "vert"
 "-o"
 "/tmp/jl_ESOKcc"

Run glslang.

run(pipeline(`$glslang $flags`, stdin = _stdin))
Process(`/home/runner/.julia/artifacts/f1fa93f41410326ba4ca250dbf71306ccc966830/bin/glslangValidator --stdin -V -S vert -o /tmp/jl_ESOKcc`, ProcessExited(0))

Read the code and clean the temporary file.

spirv_code = reinterpret(UInt32, read(path))
rm(path)
@assert first(spirv_code) == 0x07230203 # SPIR-V magic number
spirv_code
118-element reinterpret(UInt32, ::Vector{UInt8}):
 0x07230203
 0x00010000
 0x0008000a
 0x00000013
 0x00000000
 0x00020011
 0x00000001
 0x0006000b
 0x00000001
 0x4c534c47
          ⋮
 0x00000010
 0x00000011
 0x0000000e
 0x0000000f
 0x0003003e
 0x00000009
 0x00000012
 0x000100fd
 0x00010038

This page was generated using Literate.jl.