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
- Pass rowStride = 0 for packed pixel formats and let ComputePitch determine the layout.
- Convert the image to an unpacked format (e.g. R8G8B8A8_UNorm) before applying a custom stride.
- Use PitchFlags appropriate for the format instead of a manual stride.
- 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
- Never combine packed formats (YUV/BC) with manual strides.
- Convert packed formats to RGBA before custom-stride wrapping.
- Check ComputePitch's packed outputs when supporting new formats.
- Prefer PitchFlags over manual stride values for special layouts.
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
- Unsupported DXGI Format
- sizeof(TData) / sizeof(Format) * Width is not an integer
- The camera [ ] is disabled and can't be attached
- The camera [ ] is already attached
- The camera [ ] isn't attached
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)