stride3d/stride · error · NotImplementedException

Can't process argument {i + 1} of type {parameterType} in me

Error message

Can't process argument {i + 1} of type {parameterType} in method {entryPoint.Id.Name}

What it means

During SPIR-V entry-point wrapper generation for tessellation shaders (hull/domain), FillTessellationArguments walks each parameter of the entry point and maps recognized SDSL stream/patch parameter types to SPIR-V arguments. This NotImplementedException is thrown when a parameter's underlying type matches none of the supported cases (PatchType input/output, StreamsType Constants with no/in modifier, StreamsType Output/Constants with out modifier) while the argument slot is still 0 (unfilled). It means the wrapper generator has no translation strategy for that parameter type — an unimplemented feature, not user data corruption.

Solutions

  1. Change the offending parameter to a supported SDSL type: PatchType for input/output patches, or StreamsType Output/Constants with the correct `out` (or plain/in for constants) modifier
  2. Check that HS_OUTPUT / HS_CONSTANTS parameters are declared `out` — without the modifier they fall through to the throw
  3. If the parameter is genuinely needed, extend FillTessellationArguments in EntryPointWrapperGenerator.cs with a new case that materializes a Function-storage OpVariable and assigns arguments[i]
  4. Reorder or remove the unsupported parameter so the entry point signature only contains types the generator knows

Example fix

// before (unsupported signature)
void HSMain(InputPatch<VertexOutput, 3> patch, float3 extra)
// after (only supported parameter kinds)
void HSMain(InputPatch<VertexOutput, 3> patch, out HS_OUTPUT output)
Defensive patterns

Strategy: validation

Validate before calling

// Before registering a tessellation entry point, verify each parameter maps to a known kind
static bool IsSupportedTessParameter(FunctionType fn) =>
    fn.ParameterTypes.All(p =>
        ((PointerType)p.Type).BaseType is PatchType
        or StreamsType { Kind: StreamsKindSDSL.Constants }
        or (StreamsType { Kind: StreamsKindSDSL.Output or StreamsKindSDSL.Constants } and { }));

Type guard

static bool IsStreamsOrPatch(ParameterType p) =>
    ((PointerType)p.Type).BaseType is PatchType or StreamsType;

Prevention

When it happens

Trigger: Declaring a tessellation control/evaluation entry point whose signature contains a parameter whose pointee type is not a recognized PatchType or StreamsType (e.g. a raw struct, scalar, or a StreamsType in an unhandled modifier combination such as a plain 'in' Output stream or a ref parameter of an unexpected kind). The switch falls to `case var t when arguments[i] == 0` and throws with the 1-based parameter index, type, and entry-point name.

Common situations: Writing a custom hull/domain shader in Stride with a hand-written signature that doesn't follow the SDSL tessellation conventions; upgrading Stride/SDSL where a new parameter kind was introduced but wrapper generation wasn't extended; typos like missing `out` modifier on an HS_OUTPUT/HS_CONSTANTS parameter so it no longer matches any case.

Related errors


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

Appendix: source

Thrown at sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs:244

                                        buffer.Add(new OpStore(inputPtr, inputResult, null, []));
                                    }
                                    break;
                                }
                            case StreamsType t when t.Kind is StreamsKindSDSL.Output or StreamsKindSDSL.Constants && parameterModifiers == ParameterModifiers.Out:
                                {
                                    // Parameter is "out HS_OUTPUT output" or "out HS_CONSTANTS constants"
                                    var structType = t.Kind switch
                                    {
                                        StreamsKindSDSL.Output => streamLayout.OutputType,
                                        StreamsKindSDSL.Constants => streamLayout.ConstantsType!,
                                        _ => throw new NotSupportedException($"Unsupported StreamsKindSDSL for output parameter: {t.Kind}"),
                                    };
                                    var outVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(structType, Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId;
                                    arguments[i] = outVariable;
                                    break;
                                }
                            case var t when arguments[i] == 0:
                                throw new NotImplementedException($"Can't process argument {i + 1} of type {parameterType} in method {entryPoint.Id.Name}");
                        }
                    }
                }

                void ProcessTessellationArguments(Symbol function, Span<int> arguments)
                {
                    var functionType = (FunctionType)function.Type;
                    for (int i = 0; i < functionType.ParameterTypes.Count; i++)
                    {
                        var parameterType = ((PointerType)functionType.ParameterTypes[i].Type).BaseType;
                        var parameterModifiers = functionType.ParameterTypes[i].Modifiers;
                        switch (parameterType)
                        {
                            case StreamsType { Kind: StreamsKindSDSL.Output } when parameterModifiers == ParameterModifiers.Out:
                                {
                                    // Parameter is "out HS_OUTPUT output"
                                    var outputVariable = arguments[i];
                                    // Load as value

View on GitHub (pinned to 96fad776d2)