stride3d/stride · error · ArgumentException

Can not use more than

Error message

Can not use more than {CommandList.MaxViewportAndScissorRectangleCount} viewports simultaneously

What it means

SetViewports rejects any viewport array whose length exceeds CommandList.MaxViewportAndScissorRectangleCount (a hardware-derived constant). Passing more viewports than the graphics device supports would otherwise cause a driver-level error. The message interpolates the actual constant at runtime.

Solutions

  1. Cap the span length to CommandList.MaxViewportAndScissorRectangleCount before calling
  2. Batch viewport groups and call SetViewports multiple times per draw where possible
  3. Verify the constant at runtime and configure viewport arrays from it

Example fix

// before
var viewports = BuildAllViewports(); // 32 entries
effect.SetViewports(viewports);
// after
var viewports = BuildAllViewports();
if (viewports.Length > CommandList.MaxViewportAndScissorRectangleCount)
    viewports = viewports.Slice(0, CommandList.MaxViewportAndScissorRectangleCount);
effect.SetViewports(viewports);
Defensive patterns

Strategy: validation

Validate before calling

if (values.Length > CommandList.MaxViewportAndScissorRectangleCount) throw new ArgumentException("too many viewports");

Try / catch

try { effect.SetViewports(span); } catch (ArgumentException) { /* truncate span and retry */ }

Prevention

When it happens

Trigger: Calling effect.SetViewports(ReadOnlySpan<Viewport>) with a span of length > MaxViewportAndScissorRectangleCount (typically 16, D3D hardware limit); called indirectly by SetViewport overloads.

Common situations: Rendering multiple simultaneous viewports (split-screen / shadow cascades) and miscounting; porting code from a device with a higher viewport limit; passing an unbounded list converted to a span.

Related errors


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

Appendix: source

Thrown at sources/engine/Stride.Rendering/Rendering/Images/ImageEffect.cs:177

                var viewport = value.Value;
                SetViewports(MemoryMarshal.CreateReadOnlySpan(ref viewport, 1));
            }
            else
            {
                SetViewports(ReadOnlySpan<Viewport>.Empty);
            }
        }

        /// <summary>
        /// Binds a set of viewports to the rasterizer stage.
        /// </summary>
        /// <param name="values">The set of viewports to bind.</param>
        /// <remarks>Only <see cref="CommandList"/>'s `MaxViewportAndScissorRectangleCount` scissors can be used simultaneously</remarks>
        public void SetViewports(ReadOnlySpan<Viewport> values)
        {
            if (values.Length > CommandList.MaxViewportAndScissorRectangleCount)
            {
                throw new ArgumentException($"Can not use more than {CommandList.MaxViewportAndScissorRectangleCount} viewports simultaneously");
            }

            boundViewportCount = values.Length;
            values.CopyTo(viewports);
        }

        /// <summary>
        /// Binds a single scissor rectangle to the rasterizer stage.
        /// </summary>
        /// <param name="value">The scissor rectangle.</param>
        public void SetScissorRectangle(Rectangle? value)
        {
            if (value.HasValue)
            {
                var scissor = value.Value;
                SetScissorRectangles(MemoryMarshal.CreateReadOnlySpan(ref scissor, 1));
            }
            else

View on GitHub (pinned to 96fad776d2)