stride3d/stride · error · NotImplementedException

System-value Semantic not implemented: {semantic2} for stage

Error message

System-value Semantic not implemented: {semantic2} for stage {executionModel} as {type}

What it means

BuiltinProcessor.ProcessBuiltinsDecoration maps D3D-style SV_ system-value semantics (e.g. SV_GroupID, SV_Position) to SPIR-V BuiltIn decorations for each shader stage. When an SV_ semantic is encountered for a stage/usage combination that has no mapping in the switch expression, it throws NotImplementedException because the generator cannot emit a correct SPIR-V builtin. This is an intentional 'unsupported feature' guard, not a user-data validation error.

Solutions

  1. Check the mapped cases in BuiltinProcessor.cs and change the semantic to one supported for your ExecutionModel (e.g. use SV_GROUPID only in a GLCompute entry point).
  2. Fix typos in the semantic name so it matches an exact mapped entry (case-insensitive SV_GROUPID, SV_GROUPTHREADID, etc.).
  3. If the semantic is genuinely needed, add a mapping arm to the switch in BuiltinProcessor mapping it to the appropriate Spv.Specification BuiltIn value.
  4. For unsupported system values, pass the data in via a regular input/binding (e.g. a push constant or SSBO populated by the engine) instead of an SV_ semantic.
  5. Vote for / implement the missing stage support (e.g. tessellation domain semantics) upstream in Stride's shader processor.

Example fix

// before (in a GLCompute stage)
float2 SV_Position : SV_Position; // SV_Position unmapped for GLCompute input -> NotImplementedException

// after
uint3 SV_DispatchThreadID : SV_DISPATCHTHREADID; // explicitly mapped for GLCompute -> BuiltIn.GlobalInvocationId
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check semantics against known mappings before invoking the processor
static readonly HashSet<string> KnownSv = new(StringComparer.OrdinalIgnoreCase)
    { "SV_OUTPUTCONTROLPOINTID", "SV_GROUPID", "SV_GROUPINDEX", "SV_GROUPTHREADID", "SV_DISPATCHTHREADID" };
bool IsSupported(string semantic) => !semantic.StartsWith("SV_", StringComparison.OrdinalIgnoreCase) || KnownSv.Contains(semantic);

Type guard

static bool IsMappedSystemValue(string semantic, ExecutionModel model) =>
    !semantic.StartsWith("SV_", StringComparison.OrdinalIgnoreCase) ||
    (model == ExecutionModel.GLCompute && new[]{"SV_GROUPID","SV_GROUPINDEX","SV_GROUPTHREADID","SV_DISPATCHTHREADID"}.Any(s => s.Equals(semantic, StringComparison.OrdinalIgnoreCase)) ||
     model == ExecutionModel.TessellationControl && semantic.Equals("SV_OUTPUTCONTROLPOINTID", StringComparison.OrdinalIgnoreCase));

Try / catch

try
{
    BuiltinProcessor.ProcessBuiltinsDecoration(context, executionModel, variableId, StreamVariableType.Input, semantic, ref type);
}
catch (NotImplementedException ex)
{
    log.Error($"System value '{semantic}' unsupported for stage {executionModel}: {ex.Message}");
    throw new ShaderCompilationException($"Unsupported system value {semantic} for stage {executionModel}", ex);
}

Prevention

When it happens

Trigger: Calling ProcessBuiltinsDecoration (directly or via EntryPointWrapperGenerator.GenerateWrapper) with a StreamVariableType.Input semantic starting with "SV_" whose (ExecutionModel, StreamVariableType, semantic) tuple is not one of the explicitly mapped cases (e.g. SV_Position in a GLCompute stage, SV_TessFactor, SV_InsideTessFactor, SV_DomainLocation, or any unmapped SV_ name), or any SV_ semantic used as an Output stream.

Common situations: Porting HLSL shaders using system-value semantics Stride's SPIR-V frontend does not yet translate for the target stage; using an SV_ semantic in a stage where HLSL exposes it but the processor lacks a mapping; custom SDSL streams referencing newer or exotic system values; semantic typos like SV_POSITON that miss the exact mapped names.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs:138

            (ExecutionModel.Vertex, StreamVariableType.Input, "SV_INSTANCEID") => AddBuiltin(context, variable, BuiltIn.InstanceIndex),
            (ExecutionModel.Vertex, StreamVariableType.Input, "SV_VERTEXID") => AddBuiltin(context, variable, BuiltIn.VertexIndex),
            ( >= ExecutionModel.Vertex, _, "SV_INSTANCEID" or "SV_VERTEXID") => false, // forward from VS to the next stages
            // Pixel shader inputs (SV_IsFrontFace)
            (ExecutionModel.Fragment, StreamVariableType.Input, "SV_ISFRONTFACE") => AddBuiltin(context, variable, BuiltIn.FrontFacing),
            // SV_PrimitiveID
            (ExecutionModel.Geometry, StreamVariableType.Output, "SV_PRIMITIVEID") => AddBuiltin(context, variable, BuiltIn.PrimitiveId),
            (not ExecutionModel.Vertex, StreamVariableType.Input, "SV_PRIMITIVEID") => AddBuiltin(context, variable, BuiltIn.PrimitiveId),
            // Tessellation
            (ExecutionModel.TessellationControl or ExecutionModel.TessellationEvaluation, _, "SV_TESSFACTOR") => AddBuiltin(context, variable, BuiltIn.TessLevelOuter),
            (ExecutionModel.TessellationControl or ExecutionModel.TessellationEvaluation, _, "SV_INSIDETESSFACTOR") => AddBuiltin(context, variable, BuiltIn.TessLevelInner),
            (ExecutionModel.TessellationEvaluation, StreamVariableType.Input, "SV_DOMAINLOCATION") => AddBuiltin(context, variable, BuiltIn.TessCoord),
            (ExecutionModel.TessellationControl, StreamVariableType.Input, "SV_OUTPUTCONTROLPOINTID") => AddBuiltin(context, variable, BuiltIn.InvocationId),
            // Compute shaders
            (ExecutionModel.GLCompute, StreamVariableType.Input, "SV_GROUPID") => AddBuiltin(context, variable, BuiltIn.WorkgroupId),
            (ExecutionModel.GLCompute, StreamVariableType.Input, "SV_GROUPINDEX") => AddBuiltin(context, variable, BuiltIn.LocalInvocationIndex),
            (ExecutionModel.GLCompute, StreamVariableType.Input, "SV_GROUPTHREADID") => AddBuiltin(context, variable, BuiltIn.LocalInvocationId),
            (ExecutionModel.GLCompute, StreamVariableType.Input, "SV_DISPATCHTHREADID") => AddBuiltin(context, variable, BuiltIn.GlobalInvocationId),
            (_, _, { } semantic2) when semantic2.StartsWith("SV_") => throw new NotImplementedException($"System-value Semantic not implemented: {semantic2} for stage {executionModel} as {type}"),
            _ => false,
        };
    }
}

View on GitHub (pinned to 96fad776d2)