stride3d/stride · error · NotSupportedException

Unsupported qualifier value

Error message

Unsupported qualifier value: {intrinsicDefinition.Parameters[i].Qualifier}

What it means

The expander maps SDSL Qualifier values (in/out/inout/ref) to SPIR-V-facing ParameterModifiers. A qualifier outside this set has no mapping, so the expansion of the intrinsic's parameter list fails with this NotSupportedException.

Solutions

  1. Change the parameter qualifier to one of in/out/inout/ref (or omit it)
  2. Remove unsupported qualifiers like const/uniform from intrinsic parameter declarations
  3. If a new qualifier is legitimate, extend the mapping switch in IntrinsicTemplateExpander

Example fix

// before
void myIntrin(const float x);
// after
void myIntrin(in float x);
Defensive patterns

Strategy: validation

Validate before calling

static readonly HashSet<Qualifier?> Allowed = new() { Qualifier.In, Qualifier.Out, Qualifier.InOut, Qualifier.Ref, null };
if (intrinsicDefinition.Parameters.Any(p => !Allowed.Contains(p.Qualifier)))
    throw new NotSupportedException("Intrinsic parameter uses unsupported qualifier");

Type guard

bool IsSupportedQualifier(Qualifier? q) => q is null or Qualifier.In or Qualifier.Out or Qualifier.InOut or Qualifier.Ref;

Try / catch

try { Expand(intrinsic, args); }
catch (NotSupportedException ex) when (ex.Message.Contains("Unsupported qualifier value")) { /* flag the .sdsl declaration */ }

Prevention

When it happens

Trigger: An intrinsic parameter declares a Qualifier value other than In, Out, InOut, Ref, or null in the .sdsl intrinsic definition.

Common situations: Custom qualifiers added by newer Stride versions or user extensions that the intrinsic expander does not recognize; copy-pasted qualifiers from other shading languages (e.g. 'uniform', 'const') into intrinsic parameter lists.

Related errors


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

Appendix: source

Thrown at sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs:384

                        // Note: we remove auto matrix loop if result type is not either void or matrix of the desired size
                        if (autoMatrixLoop != null)
                        {
                            if (parameterTypes[0] != ScalarType.Void && (parameterTypes[0] is not MatrixType || parameterTypeHelper[0].Size1.Generator != autoMatrixLoop))
                                autoMatrixLoop = null;
                        }

                        var functionParameters = new List<FunctionParameter>();
                        for (int i = 0; i < intrinsicDefinition.Parameters.Length; ++i)
                        {
                            var paramType = (SymbolType)parameterTypes[i + 1];
                            var modifier = intrinsicDefinition.Parameters[i].Qualifier switch
                            {
                                Qualifier.In => ParameterModifiers.In,
                                Qualifier.Out => ParameterModifiers.Out,
                                Qualifier.InOut => ParameterModifiers.InOut,
                                Qualifier.Ref => ParameterModifiers.Ref,
                                null => ParameterModifiers.None,
                                _ => throw new NotSupportedException($"Unsupported qualifier value: {intrinsicDefinition.Parameters[i].Qualifier}"),
                            };

                            // Wrap out/inout/ref parameters in PointerType, matching user-defined function convention
                            if ((modifier & ParameterModifiers.Out) != 0 || modifier == ParameterModifiers.Ref)
                                paramType = new PointerType(paramType, Specification.StorageClass.Function);

                            functionParameters.Add(new(paramType, modifier));
                        }
                        var functionType = new FunctionType(parameterTypes[0], functionParameters);

                        result.Add(new(functionType, autoMatrixLoop?.Locations, autoMatrixLoopSize));
                    }
                }
            }

            intrinsicDefinitionsCache.Add(name, result);
            return true;
        }

View on GitHub (pinned to 96fad776d2)