stride3d/stride · error · ArgumentException
sizeof(TData) / sizeof(Format) * Width is not an integer
Error message
sizeof(TData) / sizeof(Format) * Width is not an integer
What it means
CalculateWidth derives how many TData elements span the texture width based on row stride (mipWidth * Format.SizeInBytes) versus the size of the caller's element type. If rowStride * mipWidth is not evenly divisible by sizeof(TData) — i.e. sizeof(TData)/sizeof(Format)*Width is not an integer — ArgumentException is thrown.
Solutions
- Choose a TData whose size in bytes evenly divides the row stride — typically Format.SizeInBytes itself or a divisor of it.
- Use the format's native pixel struct as TData (e.g. Half4 for R16G16B16A16).
- Compute a valid element size: sizeof(TData) must satisfy (mipWidth * Format.SizeInBytes * mipWidth) % sizeof(TData) == 0.
Example fix
// before texture.CalculateWidth<byte>(mipWidth); // element type mismatched to row stride // after texture.CalculateWidth<Half4>(mipWidth); // 8 bytes matches format pixel size
Defensive patterns
Strategy: validation
Validate before calling
int rowStride = width * format.SizeInBytes;
if (rowStride % sizeof(TData) != 0)
throw new InvalidOperationException($"sizeof(TData)={sizeof(TData)} incompatible with row stride {rowStride}"); Type guard
static bool ElementTypeFitsRow<TData>(PixelFormat fmt, int width) where TData : unmanaged => (width * fmt.SizeInBytes) % sizeof(TData) == 0;
Try / catch
try { w = texture.CalculateWidth<TData>(mipWidth); }
catch (ArgumentException ex)
{
logger.LogError(ex, "TData size incompatible with format {Fmt}", texture.Format);
throw;
} Prevention
- Use the format's native pixel-size struct as TData.
- Check Format.SizeInBytes before choosing a generic element type.
- Avoid byte-based buffers for wide formats when the stride math does not divide evenly.
When it happens
Trigger: Calling CalculateWidth<TData> with a TData whose byte size is incompatible with the pixel row size, e.g. reading a wide format texture using byte[] or int[] elements such that rowStride * mipWidth is not a multiple of sizeof(TData).
Common situations: Pixel-copy utilities using byte buffers for multi-byte formats; generic CPU-side texture processing code that assumes 4-byte pixels; block-compressed formats with odd byte sizes.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Custom strides is not supported with packed PixelFormats
- Unsupported DXGI Format
- 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/1c4660ccaf9451ba.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Graphics/Texture.cs:859
/// int widthAsFloats = texture.CalculateWidth<float>(); // 100 floats
/// </code>
/// </para>
/// </remarks>
/// <exception cref="ArgumentException">
/// The largestSize of <see cref="Format"/> and the largestSize of <typeparamref name="TData"/> does not match.
/// The ratio between the two must be an integer, or else there would be remaining bytes.
/// </exception>
public unsafe int CalculateWidth<TData>(int mipLevel = 0) where TData : unmanaged
{
var mipWidth = CalculateMipSize(Width, mipLevel);
var rowStride = mipWidth * Format.SizeInBytes;
var dataStrideInBytes = mipWidth * sizeof(TData);
var (width, rem) = Math.DivRem(rowStride * mipWidth, dataStrideInBytes);
if (rem != 0)
throw new ArgumentException("sizeof(TData) / sizeof(Format) * Width is not an integer");
return width;
}
/// <summary>
/// Calculates the number of pixel elements of type <typeparamref name="TData"/> the Texture requires
/// for a particular mip-level.
/// </summary>
/// <typeparam name="TData">The type of the pixel data.</typeparam>
/// <param name="mipLevel">
/// The mip-level for which to calculate the width.
/// By default, the first mip-level at index 0 is selected, which is the most detailed one.
/// </param>
/// <returns>
/// The expected number of <typeparamref name="TData"/> elements of the Texture for the mip-level specified by <paramref name="mipLevel"/>.
/// </returns>
/// <remarks>
/// This method can be used to allocate a Texture data buffer to hold pixel data of type <typeparamref name="TData"/> as follows:View on GitHub (pinned to 96fad776d2)