stride3d/stride · error · InvalidOperationException

Custom strides is not supported with packed PixelFormats

Error message

Custom strides is not supported with packed PixelFormats

What it means

ComputePitch can pack pixels (widthPacked/heightPacked differ from w/h) for certain block or packed pixel formats. For those formats a custom rowStride cannot be honored because the pitched layout is fixed by the packing; the API throws rather than computing a wrong slice pitch.

Solutions

  1. Pass rowStride = 0 for packed pixel formats and let ComputePitch determine the layout.
  2. Convert the image to an unpacked format (e.g. R8G8B8A8_UNorm) before applying a custom stride.
  3. Use PitchFlags appropriate for the format instead of a manual stride.
  4. If the source buffer is truly row-padded packed data, repack it into the expected tight layout first.

Example fix

// before
var img = Image.New(desc, ptr, 0, null, false, PitchFlags.None, rowStride: 2048); // packed format
// after
var img = Image.New(desc, ptr, 0, null, false, PitchFlags.None, rowStride: 0); // let ComputePitch handle packed formats
Defensive patterns

Strategy: validation

Validate before calling

Image.ComputePitch(format, w, h, out _, out _, out var wPacked, out var hPacked, PitchFlags.None);
bool packed = wPacked != w || hPacked != h;
if (packed && rowStride > 0)
    throw new ArgumentException("Custom stride unsupported for packed format " + format);

Type guard

null

Try / catch

try { img = Image.New(desc, ptr, 0, null, false, flags, rowStride); }
catch (InvalidOperationException ex) when (ex.Message.Contains("packed PixelFormats"))
{
    img = Image.New(desc, ptr, 0, null, false, flags, 0);
}

Prevention

When it happens

Trigger: Supplying rowStride > 0 for a packed pixel format (e.g. R8G8_B8G8_UNorm, UYVY-style, or block formats where width/height get packed by ComputePitch) so that widthPacked != w or heightPacked != h.

Common situations: Video/YUV packed formats being wrapped with a stride from a capture device; using block-compressed formats (BC*) with a custom stride copied from a GPU texture description.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at sources/engine/Stride.Foundation/Graphics/Image.cs:1030

            for (int j = 0; j < imageDesc.ArraySize; j++)
            {
                int w = imageDesc.Width;
                int h = imageDesc.Height;
                int d = imageDesc.Depth;

                for (int i = 0; i < imageDesc.MipLevels; i++)
                {
                    ComputePitch(imageDesc.Format, w, h, out var rowPitch, out var slicePitch, out var widthPacked, out var heightPacked, pitchFlags);

                    if (rowStride > 0)
                    {
                        // Check that stride is ok
                        if (rowStride < rowPitch)
                            throw new InvalidOperationException($"Invalid stride [{rowStride}]. Value can't be lower than actual stride [{rowPitch}]");

                        if (widthPacked != w || heightPacked != h)
                            throw new InvalidOperationException("Custom strides is not supported with packed PixelFormats");

                        // Recalculate slice pitch
                        slicePitch = rowStride * h;
                    }

                    // Store the number of z-slicec per miplevels
                    if (j == 0)
                        mipmapToZIndex.Add(bufferCount);

                    // Keep a trace of indices for the 1st array size, for each mip levels
                    pixelSizeInBytes += d * slicePitch;
                    bufferCount += d;

                    if (h > 1)
                        h >>= 1;

                    if (w > 1)
                        w >>= 1;

View on GitHub (pinned to 96fad776d2)