Class EffectCompiler
- Namespace
- ShadowDusk.Compiler
- Assembly
- ShadowDusk.Compiler.dll
The product's in-memory shader compiler and the default IShaderCompiler
implementation: HLSL .fx source in, .mgfx bytes out, on Linux, macOS, or
Windows with nothing but this library. Orchestrates the faithful pipeline —
HLSL → DXC → SPIR-V → SPIRV-Cross → GLSL for OpenGL, and HLSL → vkd3d-shader → DXBC for
DirectX — and writes the MonoGame/KNI .mgfx container.
public sealed class EffectCompiler : IShaderCompiler
- Inheritance
-
EffectCompiler
- Implements
- Inherited Members
Remarks
Construct with the default constructor for normal use (new EffectCompiler()); the
optional factory parameters exist only to inject alternative pipeline components (e.g. the
pure-managed SpirvReflector for the WASM host). The output loads into MonoGame's
Effect and renders the same image as mgfxc's, but is not byte-identical to it.
Constructors
EffectCompiler(Func<IDxcShaderCompiler>?, Func<ISpirvToGlslTranspiler>?, Func<IShaderReflector>?, Func<IDxbcShaderCompiler>?)
Creates an EffectCompiler. Pass no arguments for the standard, self-contained desktop pipeline. The optional factories override individual pipeline components for advanced/host-specific scenarios.
public EffectCompiler(Func<IDxcShaderCompiler>? dxcCompilerFactory = null, Func<ISpirvToGlslTranspiler>? glslTranspilerFactory = null, Func<IShaderReflector>? reflectorFactory = null, Func<IDxbcShaderCompiler>? dxbcCompilerFactory = null)
Parameters
dxcCompilerFactoryFunc<IDxcShaderCompiler>Optional factory for the HLSL → SPIR-V DXC frontend. Defaults to the bundled (Vortice.Dxc) desktop DXC.
glslTranspilerFactoryFunc<ISpirvToGlslTranspiler>Optional factory for the SPIR-V → GLSL transpiler. Defaults to the SPIRV-Cross-backed transpiler.
reflectorFactoryFunc<IShaderReflector>Optional factory for the shader reflector. When null the OpenGL path reflects from the native DXIL oracle; the WASM host injects the pure-managed
SpirvReflectorinstead.dxbcCompilerFactoryFunc<IDxbcShaderCompiler>Optional factory for the HLSL → DXBC / D3D-bytecode backend (the DirectX and FNA targets). When null (the desktop default) the backend is selected from DxbcBackend for DirectX and is always the native vkd3d-shader backend for FNA — byte-for-byte the pre-existing behavior. The WASM host injects its browser vkd3d backend (
WasmVkd3dShaderCompiler) here — the SAME pinned vkd3d 1.17, never a substitute compiler.
Methods
Compile(string, CompilerOptions, CancellationToken)
Synchronous counterpart of CompileAsync(string, CompilerOptions, CancellationToken): compiles the given HLSL
source into a compiled effect for the target in options, on the
calling thread, returning the effect bytes in memory. Intended for synchronous call
sites that cannot await — e.g. compiling inside MonoGame/KNI's
Content.Load<Effect>.
public Result<CompiledShader, ShaderError[]> Compile(string hlslSource, CompilerOptions options, CancellationToken cancellationToken = default)
Parameters
hlslSourcestringThe HLSL
.fxeffect source to compile.optionsCompilerOptionsCompilation settings: the PlatformTarget, include resolution, debug mode, MGFX version, and DirectX DXBC backend selection.
cancellationTokenCancellationTokenToken observed between pipeline stages.
Returns
- Result<CompiledShader, ShaderError[]>
A Result<T, TError> that is either a successful CompiledShader (the target plus its effect bytes) or, on failure, an array of ShaderError with source file, line, column, code, and message. Compilation failures are returned as errors, not thrown as exceptions.
Remarks
Runs the exact same pipeline as CompileAsync(string, CompilerOptions, CancellationToken) (one shared
implementation, never a fork), so for the same source, options, and compiler
version the output bytes are identical. The whole compile runs on the calling
thread and never blocks on a task internally — safe on single-threaded browser
WASM. Precondition on the browser/WASM host: InitializeAsync(CancellationToken)
must have completed first (the WASM compiler modules load asynchronously);
otherwise this returns a clear ShaderError (code SD1903)
telling the caller to await InitializeAsync(CancellationToken). On desktop no prior
initialization is required.
CompileAsync(string, CompilerOptions, CancellationToken)
Compiles the given HLSL source into a compiled effect for the target in
options, returning the effect bytes in memory.
public Task<Result<CompiledShader, ShaderError[]>> CompileAsync(string hlslSource, CompilerOptions options, CancellationToken cancellationToken = default)
Parameters
hlslSourcestringThe HLSL
.fxeffect source to compile.optionsCompilerOptionsCompilation settings: the PlatformTarget, include resolution, debug mode, MGFX version, and DirectX DXBC backend selection.
cancellationTokenCancellationTokenToken used to cancel a long-running compile.
Returns
- Task<Result<CompiledShader, ShaderError[]>>
A Result<T, TError> that is either a successful CompiledShader (the target plus its effect bytes) or, on failure, an array of ShaderError with source file, line, column, code, and message. Compilation failures are returned as errors, not thrown as exceptions.
Remarks
A thin asynchronous shell over the same synchronous pipeline core Compile(string, CompilerOptions, CancellationToken) runs (one implementation — output is byte-identical by construction). The compile is offloaded to the thread pool so the caller's thread is never blocked by the native compiler work.
InitializeAsync(CancellationToken)
One-time warm-up that makes the synchronous Compile(string, CompilerOptions, CancellationToken) usable from a synchronous call site. Idempotent and safe to await repeatedly. On the browser/WASM host this loads and instantiates every WASM compiler module a subsequent Compile(string, CompilerOptions, CancellationToken) of any supported target needs (DXC, SPIRV-Cross, and vkd3d-shader); on desktop it is effectively a no-op (the native compilers load lazily on first use).
public Task InitializeAsync(CancellationToken cancellationToken = default)
Parameters
cancellationTokenCancellationTokenToken used to cancel the warm-up.
Returns
- Task
A task that completes when the compiler is ready for synchronous compiles.
Remarks
Await this once from a legal async context — e.g. the Blazor bootstrap or an
async Main — before calling Compile(string, CompilerOptions, CancellationToken) from synchronous code such
as MonoGame/KNI's Content.Load<Effect>. Never block on it
(.Result / .Wait()): on single-threaded browser WASM that is the
exact sync-over-async deadlock this API exists to avoid. A failure to load a
required module (e.g. the module asset cannot be fetched) is thrown from the
returned task — loudly, with the underlying loader diagnostics.