stride3d/stride · error · InvalidOperationException
Width/Height/Depth must be power of 2
Error message
Width/Height/Depth must be power of 2
What it means
The 3D overload of Image.CalculateMipLevels requires Width/Height/Depth to be powers of two when mipLevels > 1, because mip generation for volume textures relies on clean halving. Non-power-of-two dimensions trigger an InvalidOperationException before any mip counting happens.
Solutions
- Resize width/height/depth to the next power of two before computing mip levels
- Use mipLevels <= 1 (no chain) if the size cannot be changed
- Preprocess the texture offline (e.g. in an asset pipeline step) to power-of-two dimensions
Example fix
// before int mips = Image.CalculateMipLevels(100, 100, 100, 4); // after int size = 128; // next pow2 int mips = Image.CalculateMipLevels(size, size, size, 4);
Defensive patterns
Strategy: validation
Validate before calling
bool IsPow2(int v) => v > 0 && (v & (v - 1)) == 0;
if (mipLevels > 1 && !(IsPow2(w) && IsPow2(h) && IsPow2(d)))
// resize to next power of two first Type guard
bool CanGenerateVolumeMips(int w, int h, int d, int mips) => mips <= 1 || (IsPow2(w) && IsPow2(h) && IsPow2(d));
Try / catch
try { mips = Image.CalculateMipLevels(w, h, d, count); }
catch (InvalidOperationException) { w = NextPow2(w); h = NextPow2(h); d = NextPow2(d); mips = Image.CalculateMipLevels(w, h, d, count); } Prevention
- Enforce power-of-two texture sizes in the asset pipeline for 3D/volume textures
- Add a NextPow2 helper and apply it before mip generation
When it happens
Trigger: Calling CalculateMipLevels(width, height, depth, mipLevels) with mipLevels > 1 and any of width, height, depth not a power of two — e.g. 100x100x100 with 4 mips.
Common situations: Importing artwork with arbitrary dimensions (e.g. 1920x1080) and requesting a mip chain; volume textures from medical/scientific data with non-PoT sizes; forgetting to pad/resize before mip generation.
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
- MipLevels must be <=
- Invalid Z slice index
- Image format not supported
- This file format is not yet implemented.
- Custom strides is not supported with packed PixelFormats
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/f7f40ec311a2f4a3.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Foundation/Graphics/Image.cs:674
mipLevels = 1;
}
return mipLevels;
}
/// <summary>
/// Calculates the number of miplevels for a Texture 2D.
/// </summary>
/// <param name="width">The width of the texture.</param>
/// <param name="height">The height of the texture.</param>
/// <param name="depth">The depth of the texture.</param>
/// <param name="mipLevels">A <see cref="MipMapCount"/>, set to true to calculates all mipmaps, to false to calculate only 1 miplevel, or > 1 to calculate a specific amount of levels.</param>
/// <returns>The number of miplevels.</returns>
public static int CalculateMipLevels(int width, int height, int depth, MipMapCount mipLevels)
{
if (mipLevels > 1)
{
if (!IsPow2(width) || !IsPow2(height) || !IsPow2(depth))
throw new InvalidOperationException("Width/Height/Depth must be power of 2");
int maxMips = CountMips(width, height, depth);
if (mipLevels > maxMips)
throw new InvalidOperationException($"MipLevels must be <= {maxMips}");
}
else if (mipLevels == 0)
{
if (!IsPow2(width) || !IsPow2(height) || !IsPow2(depth))
throw new InvalidOperationException("Width/Height/Depth must be power of 2");
mipLevels = CountMips(width, height, depth);
}
else
{
mipLevels = 1;
}
return mipLevels;
}View on GitHub (pinned to 96fad776d2)