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
- 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).
- Fix typos in the semantic name so it matches an exact mapped entry (case-insensitive SV_GROUPID, SV_GROUPTHREADID, etc.).
- If the semantic is genuinely needed, add a mapping arm to the switch in BuiltinProcessor mapping it to the appropriate Spv.Specification BuiltIn value.
- 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.
- 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
- Restrict SV_ semantics to the stages BuiltinProcessor maps them for (compute: SV_GROUPID/GROUPINDEX/GROUPTHREADID/DISPATCHTHREADID; tessellation control: SV_OUTPUTCONTROLPOINTID).
- Lint shaders for SV_ semantics outside the supported list before compilation.
- Keep a central enum/table of supported system values instead of free-form strings in SDSL.
- Write a unit test per (stage, semantic) pair you rely on to catch missing mappings early.
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
- Exception of type 'System.NotImplementedException' was throw
- Cast from {v1} to {m2} is not implemented (even though it sh
- Cast from {m1} to {v2} is not implemented (even though it sh
- Type conversion from {originalType} to {castType} failed aft
- Unsupported int width {type.Width}
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)