{"record":{"id":"b410afff2747f4c8","repo":"stride3d/stride","slug":"can-t-process-argument-i-1-of-type-parametertype-in-method","errorCode":null,"errorMessage":"Can't process argument {i + 1} of type {parameterType} in method {entryPoint.Id.Name}","messagePattern":"Can't process argument (.+?) of type (.+?) in method (.+?)","errorType":"validation","errorClass":"NotImplementedException","httpStatus":null,"severity":"error","filePath":"sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs","lineNumber":244,"sourceCode":"                                        buffer.Add(new OpStore(inputPtr, inputResult, null, []));\n                                    }\n                                    break;\n                                }\n                            case StreamsType t when t.Kind is StreamsKindSDSL.Output or StreamsKindSDSL.Constants && parameterModifiers == ParameterModifiers.Out:\n                                {\n                                    // Parameter is \"out HS_OUTPUT output\" or \"out HS_CONSTANTS constants\"\n                                    var structType = t.Kind switch\n                                    {\n                                        StreamsKindSDSL.Output => streamLayout.OutputType,\n                                        StreamsKindSDSL.Constants => streamLayout.ConstantsType!,\n                                        _ => throw new NotSupportedException($\"Unsupported StreamsKindSDSL for output parameter: {t.Kind}\"),\n                                    };\n                                    var outVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(structType, Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId;\n                                    arguments[i] = outVariable;\n                                    break;\n                                }\n                            case var t when arguments[i] == 0:\n                                throw new NotImplementedException($\"Can't process argument {i + 1} of type {parameterType} in method {entryPoint.Id.Name}\");\n                        }\n                    }\n                }\n\n                void ProcessTessellationArguments(Symbol function, Span<int> arguments)\n                {\n                    var functionType = (FunctionType)function.Type;\n                    for (int i = 0; i < functionType.ParameterTypes.Count; i++)\n                    {\n                        var parameterType = ((PointerType)functionType.ParameterTypes[i].Type).BaseType;\n                        var parameterModifiers = functionType.ParameterTypes[i].Modifiers;\n                        switch (parameterType)\n                        {\n                            case StreamsType { Kind: StreamsKindSDSL.Output } when parameterModifiers == ParameterModifiers.Out:\n                                {\n                                    // Parameter is \"out HS_OUTPUT output\"\n                                    var outputVariable = arguments[i];\n                                    // Load as value","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs#L226-L262","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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","Check that HS_OUTPUT / HS_CONSTANTS parameters are declared `out` — without the modifier they fall through to the throw","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]","Reorder or remove the unsupported parameter so the entry point signature only contains types the generator knows"],"exampleFix":"// before (unsupported signature)\nvoid HSMain(InputPatch<VertexOutput, 3> patch, float3 extra)\n// after (only supported parameter kinds)\nvoid HSMain(InputPatch<VertexOutput, 3> patch, out HS_OUTPUT output)","handlingStrategy":"validation","validationCode":"// Before registering a tessellation entry point, verify each parameter maps to a known kind\nstatic bool IsSupportedTessParameter(FunctionType fn) =>\n    fn.ParameterTypes.All(p =>\n        ((PointerType)p.Type).BaseType is PatchType\n        or StreamsType { Kind: StreamsKindSDSL.Constants }\n        or (StreamsType { Kind: StreamsKindSDSL.Output or StreamsKindSDSL.Constants } and { }));","typeGuard":"static bool IsStreamsOrPatch(ParameterType p) =>\n    ((PointerType)p.Type).BaseType is PatchType or StreamsType;","tryCatchPattern":null,"preventionTips":["Keep GS/HS/DS entry-point signatures to the documented SDSL parameter kinds (PatchType, out HS_OUTPUT, HS_CONSTANTS)","Always mark HS_OUTPUT/HS_CONSTANTS parameters `out`","When porting shaders from HLSL, review each parameter against SDSL tessellation conventions before compiling","When extending parameter kinds, add the matching case in FillTessellationArguments and a test"],"tags":["shader-compilation","spirv","tessellation","not-implemented","code-generation"],"backgroundTag":"method-not-implemented","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}