stride3d/stride · error · InvalidOperationException
No fragment entry point
Error message
No fragment entry point
What it means
Thrown when the probe's SPIR-V module exposes no fragment-stage entry point while building the graphics pipeline in RenderFrame. Unlike the vertex stage there is no fallback fragment shader, so a fragment entry point is mandatory.
Solutions
- Compile/export the test shader with a fragment entry point and ensure it was passed as the probe's bytecode.
- Verify with SpirvProbe (check EntryPoints / VariableStorageClasses) that the module actually contains a Fragment OpEntryPoint.
- Use the compute path (Compute()) for compute shaders instead of RenderFrame().
Example fix
// before var probe = new SpirvProbe(computeBytecode); renderer.RenderFrame(output); // after var probe = new SpirvProbe(fragmentBytecode); // module must contain a fragment entry point renderer.RenderFrame(output);
Defensive patterns
Strategy: validation
Validate before calling
if (probe.FindEntryPoint(SpirvProbe.ExecutionModelFragment) == null)
throw new InvalidOperationException("Test bytecode has no fragment entry point; cannot run RenderFrame"); Try / catch
try { renderer.RenderFrame(output); }
catch (InvalidOperationException ex) when (ex.Message == "No fragment entry point")
{
// route to the correct stage path or recompile the shader
} Prevention
- Compile a pixel/fragment stage whenever a test uses RenderFrame.
- Check the pipeline type from shader reflection before selecting RenderFrame vs Compute.
- Assert on entry points with SpirvProbe in test setup.
When it happens
Trigger: RenderFrame is called with bytecode whose OpEntryPoint instructions contain no ExecutionModel Fragment entry, causing FindEntryPoint(SpirvProbe.ExecutionModelFragment) to return null and the ?? throw to fire.
Common situations: Running a vertex-only or compute shader through the rasterization test path; a corrupted or stripped SPIR-V module; shader compiled for a stage mismatch (e.g. pixel shader saved as vertex) so no fragment entry exists.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- No compute entry point
- No vertex entry point and no fallback vertex shader
- 64bit integers
- AHardwareBuffer import requires…
- argumentsBuffer
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/acebcda98b3058c9.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Tests/FrameRenderer.Vulkan.cs:605
-1f,-1f, 0f, 0.0f, 0.0f,
-1f, 1f, 1f, 0.0f, 1.0f,
];
ReadOnlySpan<uint> indices = [0, 1, 3, 1, 2, 3];
var (vertexBuffer, _) = CreateHostBuffer((ulong)(vertices.Length * sizeof(float)), VkBufferUsageFlags.VertexBuffer, MemoryMarshal.AsBytes(vertices));
var (indexBuffer, _) = CreateHostBuffer((ulong)(indices.Length * sizeof(uint)), VkBufferUsageFlags.IndexBuffer, MemoryMarshal.AsBytes(indices));
// Vertex shader: from the test's bytecode when present, else the quad passthrough
var vertexProbe = probe;
var vertexModule = shaderModule;
var vertexEntryPoint = probe.FindEntryPoint(SpirvProbe.ExecutionModelVertex);
if (vertexEntryPoint == null)
{
vertexProbe = fallbackVertexProbe ?? throw new InvalidOperationException("No vertex entry point and no fallback vertex shader");
vertexModule = fallbackVertexModule;
vertexEntryPoint = vertexProbe.FindEntryPoint(SpirvProbe.ExecutionModelVertex);
}
var fragmentEntryPoint = probe.FindEntryPoint(SpirvProbe.ExecutionModelFragment)
?? throw new InvalidOperationException("No fragment entry point");
// Vertex attributes: POSITION/TEXCOORD from the quad buffer, other semantics from
// per-instance single-element buffers built from "stream.SEMANTIC" test parameters
var bindingDescriptions = new List<VkVertexInputBindingDescription>
{
new() { binding = 0, stride = 5 * sizeof(float), inputRate = VkVertexInputRate.Vertex },
};
var attributeDescriptions = new List<VkVertexInputAttributeDescription>();
var vertexBufferHandles = new List<VkBuffer> { vertexBuffer };
foreach (var (location, semantic) in vertexProbe.GetStageInputs(vertexEntryPoint))
{
if (semantic.StartsWith("POSITION", StringComparison.OrdinalIgnoreCase))
{
attributeDescriptions.Add(new VkVertexInputAttributeDescription { location = location, binding = 0, format = VkFormat.R32G32B32Sfloat, offset = 0 });
}
else if (semantic.StartsWith("TEXCOORD", StringComparison.OrdinalIgnoreCase))
{
attributeDescriptions.Add(new VkVertexInputAttributeDescription { location = location, binding = 0, format = VkFormat.R32G32Sfloat, offset = 3 * sizeof(float) });View on GitHub (pinned to 96fad776d2)