stride3d/stride · error · NotImplementedException

Unsupported int width

Error message

Unsupported int width {type.Width}

What it means

When resolving an OpConstant/OpSpecConstant whose type is OpTypeInt, TryGetConstantValue maps the type's Width (bit size) and Signedness to a .NET literal via a switch. Only widths <=32 and 64 with signedness 0/1 are handled; any other width throws NotImplementedException with the width in the message.

Solutions

  1. Inspect the offending module's OpTypeInt instruction and re-emit it with a standard width (8/16/32/64)
  2. Extend the switch in TryGetConstantValue to normalize other widths (e.g. treat Width<=32 as 32-bit) or add explicit support
  3. Use standard types in the shader source (int/uint/long) so the compiler emits Width 32/64
  4. If Width is 1, ensure booleans map to OpTypeBool, not OpTypeInt

Example fix

// before
{ Width: 64, Signedness: 1 } => operand.ToLiteral<long>(),
_ => throw new NotImplementedException($"Unsupported int width {type.Width}"),
// after
{ Width: 64, Signedness: 1 } => operand.ToLiteral<long>(),
{ Width: <= 32, Signedness: 1 } => operand.ToLiteral<int>(), // or normalize
_ => throw new NotImplementedException($"Unsupported int width {type.Width}"),
Defensive patterns

Strategy: validation

Validate before calling

// verify integer constant types before evaluation
bool IsSupportedIntType(OpTypeInt t) =>
    (t.Width <= 32 || t.Width == 64) && (t.Signedness == 0 || t.Signedness == 1)
    && t.Width is 8 or 16 or 32 or 64;

Type guard

bool IsSupportedIntWidth(OpTypeInt t) => t.Width is 8 or 16 or 32 or 64;

Try / catch

try
{
    context.TryGetConstantValue(id, out var value, out var typeId);
}
catch (NotImplementedException ex) when (ex.Message.StartsWith("Unsupported int width"))
{
    // re-export the shader with standard integer widths, or skip this constant
}

Prevention

When it happens

Trigger: Encountering an OpTypeInt whose Width is not 8/16/32/64 — e.g. Width values like 1 (bit type), 24, 48, or any non-standard width — while evaluating a context-dependent number.

Common situations: SPIR-V modules using exotic integer widths (rare but legal per spec); a bit-width type (Width: 1) emitted for boolean-like constants; modules produced by custom or experimental compilers.

Related errors


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

Appendix: source

Thrown at sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs:223

        if (i.Op is not (Specification.Op.OpConstant or Specification.Op.OpSpecConstant))
        {
            value = null;
            return false;
        }
        typeId = i.Data.Memory.Span[1];
        var operand = i.Data.Get("value");
        if (Buffer.TryGetInstructionById(typeId, out var typeInst))
        {
            if (typeInst.Op == Specification.Op.OpTypeInt)
            {
                var type = (OpTypeInt)typeInst;
                value = type switch
                {
                    { Width: <= 32, Signedness: 0 } => operand.ToLiteral<uint>(),
                    { Width: <= 32, Signedness: 1 } => operand.ToLiteral<int>(),
                    { Width: 64, Signedness: 0 } => operand.ToLiteral<ulong>(),
                    { Width: 64, Signedness: 1 } => operand.ToLiteral<long>(),
                    _ => throw new NotImplementedException($"Unsupported int width {type.Width}"),
                };
                return true;
            }
            else if (typeInst.Op == Specification.Op.OpTypeFloat)
            {
                var type = new OpTypeFloat(typeInst);
                value = type switch
                {
                    { Width: 16 } => operand.ToLiteral<Half>(),
                    { Width: 32 } => operand.ToLiteral<float>(),
                    { Width: 64 } => operand.ToLiteral<double>(),
                    _ => throw new NotImplementedException($"Unsupported float width {type.Width}"),
                };
                return true;
            }
            else
                throw new NotImplementedException($"Unsupported context dependent number with type {typeInst.Op}");
        }

View on GitHub (pinned to 96fad776d2)