stride3d/stride · error · NotSupportedException

Unsupported execution model

Error message

Unsupported execution model: {entryPoint.ExecutionModel}

What it means

EffectCompiler translates SPIR-V entry-point execution models to Stride ShaderStage values via a switch. Models for vertex, tessellation control/evaluation, geometry, fragment and compute are mapped; any other execution model hits the default arm and throws NotSupportedException. Stride's effect pipeline simply does not support that SPIR-V stage.

Solutions

  1. Restrict the shader to execution models Stride supports (vertex, tessellation, geometry, fragment, compute).
  2. Split the SPIR-V module so only supported entry points are compiled, and handle ray/mesh stages through a dedicated pipeline outside EffectCompiler.
  3. Remove unsupported entry points from the module (e.g. dead exports from glslang) before compilation.
  4. Recompile the GLSL/HLSL source targeting only supported stages (no VK_KHR_ray_tracing / mesh shader extensions).

Example fix

// before
#pragma shader_stage(raygeneration) // ExecutionModel.RayGeneration
void main() { ... }

// after: unsupported model removed; keep only e.g.
#pragma shader_stage(compute)
[numthreads(8,8,1)]
void main() { ... }
Defensive patterns

Strategy: validation

Validate before calling

// reject unsupported SPIR-V execution models before invoking EffectCompiler
var supportedModels = new HashSet<SpirvExecutionModel> { ExecutionModel.Vertex, ExecutionModel.TessellationControl, ExecutionModel.TessellationEvaluation, ExecutionModel.Geometry, ExecutionModel.Fragment, ExecutionModel.GLCompute };
foreach (var ep in spirvModule.EntryPoints)
    if (!supportedModels.Contains(ep.ExecutionModel))
        throw new InvalidOperationException($"Entry point '{ep.Name}' uses execution model {ep.ExecutionModel}, unsupported by Stride's effect compiler.");

Type guard

static bool IsSupportedExecutionModel(ExecutionModel model) =>
    model is ExecutionModel.Vertex or ExecutionModel.TessellationControl
        or ExecutionModel.TessellationEvaluation or ExecutionModel.Geometry
        or ExecutionModel.Fragment or ExecutionModel.GLCompute;

Try / catch

try
{
    var effect = effectCompiler.Compile(effectSource, parameters);
}
catch (NotSupportedException ex) when (ex.Message.StartsWith("Unsupported execution model"))
{
    log.Error($"SPIR-V stage not supported: {ex.Message}. Use vertex/tessellation/geometry/fragment/compute stages only.");
    throw;
}

Prevention

When it happens

Trigger: EffectCompiler.Compile processes a SPIR-V module whose OpEntryPoint uses an execution model outside {Vertex, TessellationControl, TessellationEvaluation, Geometry, Fragment, GLCompute} — e.g. RayGeneration, Intersection, AnyHit, ClosestHit, Miss, Callable, Mesh, Task — passed through ShaderSource/bytecode entry points.

Common situations: Feeding ray-tracing or mesh-shader SPIR-V into the classic effect compiler; a shader library exporting an auxiliary compute-like entry point with an exotic model; a newer Vulkan/GLSL toolchain emitting Mesh/Task shaders consumed by Stride's D3D-oriented pipeline.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/a1e18b74c5db30fa. Report an issue: GitHub.

Appendix: source

Thrown at sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs:272

                        throw;
                    }
                    var translator = new SpirvTranslator(legalizedSpirv.AsMemory());
                    var translatorEntryPoints = translator.GetEntryPoints();
                    foreach (var entryPoint in translatorEntryPoints)
                    {
                        var code = translator.Translate(Backend.Hlsl, entryPoint);

                        // Compile
                        // TODO: We could compile stages in different threads to improve compiler throughput?
                        var shaderStage = entryPoint.ExecutionModel switch
                        {
                            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

View on GitHub (pinned to 96fad776d2)