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

When CountMipLevels is asked for a specific mip count greater than 1, Stride requires the texture dimensions to be powers of two, because a fixed explicit mip chain for non-PoW2 sizes is ambiguous/unsupported. It throws InvalidOperationException when width, height, or depth is not a power of 2.

Solutions

  1. Use power-of-two texture dimensions when requesting an explicit mip count.
  2. Pass mipLevels.Count == 0 to let Stride compute the full mip chain automatically.
  3. Round dimensions up/down to the nearest power of two before the call.

Example fix

// before
int mips = Texture.CountMipLevels(1920, 1080, 1, 4); // throws
// after
int mips = Texture.CountMipLevels(2048, 2048, 1, 12); // PoW2 dims
// or let the library compute all mips:
int mips = Texture.CountMipLevels(1920, 1080, 1);
Defensive patterns

Strategy: validation

Validate before calling

if (mipCount > 1 && !(int.IsPow2(width) && int.IsPow2(height) && int.IsPow2(depth)))
    throw new InvalidOperationException($"Explicit mip count requires PoW2 dims, got {width}x{height}x{depth}");

Type guard

static bool IsPow2Dims(int w, int h, int d) => int.IsPow2(w) && int.IsPow2(h) && int.IsPow2(d);

Try / catch

try { mips = Texture.CountMipLevels(w, h, d, count); }
catch (InvalidOperationException ex)
{
    logger.LogError(ex, "NPOT dims {W}x{H} with explicit mip count", w, h);
    mips = Texture.CountMipLevels(w, h, d);
}

Prevention

When it happens

Trigger: Calling Texture.CountMipLevels(width, height, depth) with mipLevels.Count > 1 on non-power-of-two dimensions — e.g. 1920x1080 or a user-resized texture with an explicit mip count.

Common situations: Screen-sized render targets (1080p, 1440p) with manual mip specification; textures resized by user content; porting code that assumed PoW2 textures.

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


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

Appendix: source

Thrown at sources/engine/Stride.Graphics/Texture.cs:774

        /// <exception cref="ArgumentOutOfRangeException">
        ///   <paramref name="mipLevels"/> is greater than the maximum number of possible mip-levels for the provided
        ///   <paramref name="width"/>, <paramref name="height"/>, and <paramref name="depth"/>.
        /// </exception>
        /// <exception cref="ArgumentException">
        ///   <paramref name="width"/>, <paramref name="height"/>, and <paramref name="depth"/> must all be
        ///   a power of two.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        ///   The dimensions must be a <strong>power of two (2^n)</strong>.
        /// </exception>
        public static int CountMipLevels(int width, int height, int depth, MipMapCount mipLevels)
        {
            switch (mipLevels.Count)
            {
                case > 1:  // Specific number
                {
                    if (!int.IsPow2(width) || !int.IsPow2(height) || !int.IsPow2(depth))
                        throw new InvalidOperationException("Width/Height/Depth must be power of 2");

                    var maxMipLevels = CountMipLevels(width, height, depth);
                    ArgumentOutOfRangeException.ThrowIfGreaterThan(mipLevels.Count, maxMipLevels, nameof(mipLevels));
                    return mipLevels.Count;
                }
                case 0:
                    if (!int.IsPow2(width) || !int.IsPow2(height) || !int.IsPow2(depth))
                        throw new InvalidOperationException("Width/Height/Depth must be power of 2");

                    return CountMipLevels(width, height, depth);  // All mips

                default:
                    return 1;  // Single mip
            }
        }

        /// <summary>
        ///   Counts the number of mip-levels for a three-dimensional Texture.

View on GitHub (pinned to 96fad776d2)