-
Notifications
You must be signed in to change notification settings - Fork 28
/
ShaderSPIRVUtils.java
89 lines (65 loc) · 2.67 KB
/
ShaderSPIRVUtils.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package javavulkantutorial;
import org.lwjgl.system.NativeResource;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.nio.file.Paths;
import static java.lang.ClassLoader.getSystemClassLoader;
import static org.lwjgl.system.MemoryUtil.NULL;
import static org.lwjgl.util.shaderc.Shaderc.*;
public class ShaderSPIRVUtils {
public static SPIRV compileShaderFile(String shaderFile, ShaderKind shaderKind) {
return compileShaderAbsoluteFile(getSystemClassLoader().getResource(shaderFile).toExternalForm(), shaderKind);
}
public static SPIRV compileShaderAbsoluteFile(String shaderFile, ShaderKind shaderKind) {
try {
String source = new String(Files.readAllBytes(Paths.get(new URI(shaderFile))));
return compileShader(shaderFile, source, shaderKind);
} catch (IOException | URISyntaxException e) {
e.printStackTrace();
}
return null;
}
public static SPIRV compileShader(String filename, String source, ShaderKind shaderKind) {
long compiler = shaderc_compiler_initialize();
if(compiler == NULL) {
throw new RuntimeException("Failed to create shader compiler");
}
long result = shaderc_compile_into_spv(compiler, source, shaderKind.kind, filename, "main", NULL);
if(result == NULL) {
throw new RuntimeException("Failed to compile shader " + filename + " into SPIR-V");
}
if(shaderc_result_get_compilation_status(result) != shaderc_compilation_status_success) {
throw new RuntimeException("Failed to compile shader " + filename + "into SPIR-V:\n " + shaderc_result_get_error_message(result));
}
shaderc_compiler_release(compiler);
return new SPIRV(result, shaderc_result_get_bytes(result));
}
public enum ShaderKind {
VERTEX_SHADER(shaderc_glsl_vertex_shader),
GEOMETRY_SHADER(shaderc_glsl_geometry_shader),
FRAGMENT_SHADER(shaderc_glsl_fragment_shader);
private final int kind;
ShaderKind(int kind) {
this.kind = kind;
}
}
public static final class SPIRV implements NativeResource {
private final long handle;
private ByteBuffer bytecode;
public SPIRV(long handle, ByteBuffer bytecode) {
this.handle = handle;
this.bytecode = bytecode;
}
public ByteBuffer bytecode() {
return bytecode;
}
@Override
public void free() {
shaderc_result_release(handle);
bytecode = null; // Help the GC
}
}
}