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

  1. Compile/export the test shader with a fragment entry point and ensure it was passed as the probe's bytecode.
  2. Verify with SpirvProbe (check EntryPoints / VariableStorageClasses) that the module actually contains a Fragment OpEntryPoint.
  3. 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

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


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)