-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathShader.cs
211 lines (158 loc) · 5.48 KB
/
Shader.cs
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
using System;
using System.Runtime.InteropServices;
namespace Glslang.NET;
/// <summary>
/// A shader used to preprocess and parse shader code.
/// </summary>
public unsafe class Shader : SafeHandle
{
/// <summary>
/// The input settings provided when creating this shader.
/// </summary>
public readonly CompilationInput input;
internal unsafe NativeShader* ShaderPtr => (NativeShader*)handle;
/// <inheritdoc/>
public override bool IsInvalid => handle < 1;
private readonly unsafe NativeCompilationInput* nativeInputPtr;
private Utf8String? _preamble = null;
/// <summary>
/// Creates a new <see cref="Shader"/> instance.
/// </summary>
/// <param name="input">The input to use when compiling.</param>
public Shader(CompilationInput input) : base(-1, true)
{
nativeInputPtr = NativeCompilationInput.Allocate(input);
CompilationContext.EnsureInitialized();
this.input = input;
handle = (nint)GlslangNative.CreateShader(nativeInputPtr);
}
/// <inheritdoc/>
protected override bool ReleaseHandle()
{
GlslangNative.DeleteShader(ShaderPtr);
NativeCompilationInput.Free(nativeInputPtr);
handle = -1;
return true;
}
/// <summary>
/// Get the debug output of the last performed operation.
/// </summary>
public string GetDebugLog()
{
return NativeUtil.GetUtf8(GlslangNative.GetShaderInfoLog(ShaderPtr));
}
/// <summary>
/// Get the debug output of the last performed operation.
/// </summary>
public string GetInfoLog()
{
return NativeUtil.GetUtf8(GlslangNative.GetShaderInfoDebugLog(ShaderPtr));
}
/// <summary>
/// Get the preprocessed shader string.
/// </summary>
public string GetPreprocessedCode()
{
return NativeUtil.GetUtf8(GlslangNative.GetPreprocessedShaderCode(ShaderPtr));
}
/// <summary>
/// Parse the preprocessed shader string into an AST.
/// </summary>
public bool Parse()
{
return GlslangNative.ParseShader(ShaderPtr, nativeInputPtr) == 1;
}
/// <summary>
/// Preprocess the input ShaderPtr string, expand macros, and resolve include directives.
/// </summary>
public bool Preprocess()
{
return GlslangNative.PreprocessShader(ShaderPtr, nativeInputPtr) == 1;
}
/// <summary>
/// Set the default global uniform block's name.
/// </summary>
public void SetDefaultUniformBlockName(string name)
{
ArgumentNullException.ThrowIfNull(name);
GlslangNative.SetDefaultUniformBlockName(ShaderPtr, name);
}
/// <summary>
/// Set the default global uniform block's set and binding.
/// </summary>
public void SetDefaultUniformBlockSetAndBinding(uint set, uint binding)
{
GlslangNative.SetDefaultUniformBlockSetAndBinding(ShaderPtr, set, binding);
}
/// <summary>
/// Set the active GLSL version to reference when preprocessing and parsing.
/// </summary>
public void SetGLSLVersion(int version)
{
GlslangNative.SetShaderGLSLVersion(ShaderPtr, version);
}
/// <summary>
/// Set the shader options.
/// </summary>
public void SetOptions(ShaderOptions options)
{
GlslangNative.SetShaderOptions(ShaderPtr, options);
}
/// <summary>
/// Set the preamble text that is processed before any other part of the source code string.
/// </summary>
public void SetPreamble(string preamble)
{
ArgumentNullException.ThrowIfNull(preamble);
_preamble = new Utf8String(preamble, true);
GlslangNative.SetShaderPreamble(ShaderPtr, _preamble.Bytes);
}
/// <summary>
/// Set the preprocessed shader code, skipping the need to call <see cref="Preprocess"/>
/// </summary>
public void SetPreprocessedShaderCode(string code)
{
ArgumentNullException.ThrowIfNull(code);
GlslangNative.SetPreprocessedShaderCode(ShaderPtr, code);
}
/// <summary>
/// Shift the binding of the given resource type by a base.
/// </summary>
public void ShiftBinding(ResourceType resourceType, uint shiftBase)
{
GlslangNative.ShiftShaderBinding(ShaderPtr, resourceType, shiftBase);
}
/// <summary>
/// Shift the set binding of a given resource type by a base.
/// </summary>
public void ShiftBindingForSet(ResourceType resourceType, uint shiftBase, uint set)
{
GlslangNative.ShiftShaderBindingForSet(ShaderPtr, resourceType, shiftBase, set);
}
/// <summary>
/// Set the source file of this <see cref="Shader"/>
/// </summary>
public void SetSourceFile(string file)
{
ArgumentNullException.ThrowIfNull(file);
GlslangNative.SetShaderSourceFile(ShaderPtr, file);
}
/// <summary>
/// Add source text to this <see cref="Shader"/>
/// </summary>
public void AddSourceText(string text)
{
ArgumentNullException.ThrowIfNull(text);
byte* utf8String = NativeUtil.AllocateUTF8Ptr(text, out uint len, false);
GlslangNative.AddShaderSourceText(ShaderPtr, utf8String, len);
GlslangNative.Free(utf8String);
}
}
/// <summary>
/// Thrown if an already disposed <see cref="Shader"/> is used.
/// </summary>
public class ShaderDisposedException : Exception
{
internal static ShaderDisposedException Disposed = new ShaderDisposedException("Shader is disposed");
internal ShaderDisposedException(string message) : base(message) { }
}