{"record":{"id":"b0b87635dabdd666","repo":"stride3d/stride","slug":"interfaceprocessor-if-a-entry-stage-shader-is-specified-a","errorCode":null,"errorMessage":"InterfaceProcessor: If a {entry.Stage} shader is specified, a vertex shader is needed too","messagePattern":"InterfaceProcessor: If a (.+?) shader is specified, a vertex shader is needed too","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs","lineNumber":310,"sourceCode":"                                            !stream.Value.Patch && dsEntryPoint.ArrayInputSize is { } arrayInputSize ? new ArrayType(variableType, arrayInputSize) : variableType,\n                                            Specification.StorageClass.Input);\n                                        context.Add(new OpVariable(context.GetOrRegister(inputPointerType), dummyInputId, Specification.StorageClass.Input, null));\n                                        context.Add(new OpDecorate(dummyInputId, Decoration.Location, [location]));\n                                        if (variableType is ScalarType or VectorType or MatrixType && !variableType.GetElementType().IsFloating())\n                                            context.Add(new OpDecorate(dummyInputId, Decoration.Flat, []));\n                                        dsEntryPoint.InterfaceVariables.Add(dummyInputId);\n                                    }\n                                }\n                            }\n                        }\n\n                        // Reset cbuffer/resource/methods used for next stage\n                        DeadCodeRemover.ResetUsedThisStage(analysisResult, liveAnalysis);\n\n                        VariableMerger.PropagateStreamsFromPreviousStage(streams);\n\n                        if (entryPointVS == null)\n                            throw new InvalidOperationException($\"{nameof(InterfaceProcessor)}: If a {entry.Stage} shader is specified, a vertex shader is needed too\");\n                    }\n                }\n\n                if (entryPointVS != null)\n                {\n                    ReadWriteAnalyzer.AnalyzeStreamReadWrites(buffer, context, entryPointVS.IdRef, analysisResult, liveAnalysis);\n\n                    // If specific semantic are written to (i.e. SV_Position), they are expected at the end of vertex shader\n                    foreach (var stream in streams)\n                    {\n                        if (stream.Value.Semantic is { } semantic)\n                        {\n                            if (semantic.ToUpperInvariant().StartsWith(\"SV_POSITION\") && requirePosition)\n                            {\n                                stream.Value.Output = true;\n                                requirePosition = false;\n                            }\n                        }","sourceCodeStart":292,"sourceCodeEnd":328,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs#L292-L328","documentation":"While iterating the active shader stages after a non-vertex stage (HS/DS/GS), InterfaceProcessor.Process requires that a vertex shader entry point exists; tessellation and geometry stages consume vertex-stage output streams, so without VSMain the stream propagation model is incomplete and it throws.","triggerScenarios":"MergeSDSL on a module containing HSMain, DSMain, or GSMain entry points but no VSMain entry point — after processing that stage the code hits entryPointVS == null.","commonSituations":"Composing a hull/domain or geometry shader without including the vertex shader class; a mixin chain where the vertex stage class was excluded by composition overrides; compiling a tessellation-only test effect.","solutions":["Include a vertex shader mixin (exposing VSMain) in the composed ShaderSource","Verify the composition/base-class chain did not override out the vertex stage class","If the tessellation/geometry stage is intended standalone, compile it through a path that does not run InterfaceProcessor.Process"],"exampleFix":"// before\nvar shader = new ShaderSource(typeof(MyHullShader)).Compose(typeof(MyDomainShader));\n// after\nvar shader = new ShaderSource(typeof(MyVertexShader)).Compose(typeof(MyHullShader)).Compose(typeof(MyDomainShader));","handlingStrategy":"validation","validationCode":"bool hasTessOrGeometry = composition.Classes.Any(c => c.GetMethods().Any(m => m.Name is \"HSMain\" or \"DSMain\" or \"GSMain\"));\nbool hasVertex = composition.Classes.Any(c => c.GetMethods().Any(m => m.Name == \"VSMain\"));\nif (hasTessOrGeometry && !hasVertex)\n    throw new InvalidOperationException(\"Tessellation/geometry stages require a vertex shader (VSMain) in the composition.\");","typeGuard":null,"tryCatchPattern":"try\n{\n    mixer.MergeSDSL(shaderSource, options, log, out var bytecode, out _, out _, out _);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"a vertex shader is needed too\"))\n{\n    log.Error($\"Missing vertex stage in composition: {ex.Message}\");\n}","preventionTips":["Compose full pipelines (VS + optional HS/DS/GS + PS) rather than isolated stages","Check that base-class overrides do not silently drop the vertex stage class","Add pipeline-level compile tests covering tessellation/geometry effects"],"tags":["spirv","shader-compilation","missing-entry-point"],"backgroundTag":"missing-required-argument","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}