stride3d/stride · error · NotSupportedException
Unsupported shader stage
Error message
Unsupported shader stage: {shaderStage} What it means
On desktop targets, EffectCompiler derives an HLSL file suffix (vs/hs/ds/gs/ps/cs) from the resolved ShaderStage to feed FXC/DXC. A ShaderStage value outside that set hits the switch default and throws NotSupportedException. This is an internal completeness check after the execution-model mapping, so it fires only when an unmapped stage value flows into HLSL source generation.
Solutions
- Ensure each compiled entry point maps to exactly one supported ShaderStage (Vertex, Hull, Domain, Geometry, Pixel, Compute).
- Do not pass combined or custom ShaderStage flags into EffectCompiler; compile one entry point per stage.
- Update Stride so the execution-model-to-stage and stage-to-suffix switches are from the same version.
- If adding a new stage, extend both switch expressions in EffectCompiler.cs (ShaderStage mapping and stageSuffix mapping).
Example fix
// before: combined flag reaches the suffix switch
var stage = ShaderStage.Vertex | ShaderStage.Pixel; // falls through -> throws
// after: one stage per entry point
foreach (var stage in entryStages) // exactly one of vs/hs/ds/gs/ps/cs per compile
CompileStage(stage); Defensive patterns
Strategy: validation
Validate before calling
// verify each stage is a single, supported ShaderStage before compiling
private static readonly HashSet<ShaderStage> HlslStages = new()
{ ShaderStage.Vertex, ShaderStage.Hull, ShaderStage.Domain, ShaderStage.Geometry, ShaderStage.Pixel, ShaderStage.Compute };
if (entryStages.Any(s => !HlslStages.Contains(s)))
throw new InvalidOperationException("Each compiled entry point must resolve to exactly one of vs/hs/ds/gs/ps/cs stages."); Type guard
static bool IsSingleHlslStage(ShaderStage stage) =>
stage is ShaderStage.Vertex or ShaderStage.Hull or ShaderStage.Domain
or ShaderStage.Geometry or ShaderStage.Pixel or ShaderStage.Compute; Try / catch
try
{
var effect = effectCompiler.Compile(effectSource, parameters);
}
catch (NotSupportedException ex) when (ex.Message.StartsWith("Unsupported shader stage"))
{
log.Error($"Stage cannot be mapped to an HLSL suffix: {ex.Message}. Compile one entry point per single stage.");
throw;
} Prevention
- Compile one entry point per stage; never OR-combine ShaderStage flags.
- Don't define custom ShaderStage values or downstream stage mappings.
- Keep the execution-model-to-stage and stage-to-suffix code paths from the same Stride version.
- Review any plugin that mutates stage metadata before EffectCompiler runs.
When it happens
Trigger: EffectCompiler.Compile on STRIDE_PLATFORM_DESKTOP resolves a shaderStage that is not one of {Vertex, Hull, Domain, Geometry, Pixel, Compute} when building stage HLSL sources — practically only reachable if stage translation produced/amplified a nonstandard stage (e.g. a combined or unknown stage flag from the preceding mapping step).
Common situations: Custom ShaderStage values introduced by downstream code or plugins; misuse of the compiler API passing raw stage flags; a merge of stage bits rather than a single stage; compiler/version skew between the stage mapper and the suffix mapper.
Related errors
- Unsupported execution model
- Binding operation on an unsupported Effect parameter type
- Shader Stage not supported.
- An unknown EffectParameterType was found.
- Resource ' ' has slot in but slot was expected (from SDSL…
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/30163d9bbd4f594e.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs:284
ExecutionModel.Vertex => ShaderStage.Vertex,
ExecutionModel.TessellationControl => ShaderStage.Hull,
ExecutionModel.TessellationEvaluation => ShaderStage.Domain,
ExecutionModel.Geometry => ShaderStage.Geometry,
ExecutionModel.Fragment => ShaderStage.Pixel,
ExecutionModel.GLCompute => ShaderStage.Compute,
_ => throw new NotSupportedException($"Unsupported execution model: {entryPoint.ExecutionModel}"),
};
#if STRIDE_PLATFORM_DESKTOP
var stageSuffix = shaderStage switch
{
ShaderStage.Vertex => "vs",
ShaderStage.Hull => "hs",
ShaderStage.Domain => "ds",
ShaderStage.Geometry => "gs",
ShaderStage.Pixel => "ps",
ShaderStage.Compute => "cs",
_ => throw new NotSupportedException($"Unsupported shader stage: {shaderStage}"),
};
stageHlslSources.Add((stageSuffix, code));
string? stageFilename = null;
#else
string? stageFilename = null;
#endif
var result = compiler!.Compile(code, entryPoint.TranslatedName, shaderStage, effectParameters, bytecode.Reflection, stageFilename);
result.CopyTo(log);
if (result.HasErrors)
{
continue;
}
// Guard against a silent null bytecode (actionable message instead of NRE below).
if (result.Bytecode is null)
{
log.Error($"Shader compilation for stage {shaderStage} (entry '{entryPoint.TranslatedName}') produced no bytecode and no error.");View on GitHub (pinned to 96fad776d2)