stride3d/stride · error · NotSupportedException
OpBitcast operand type
Error message
OpBitcast operand type {bitcastOperand.GetType()} is not supported What it means
For OpBitcast folding, the constant operand must be an int, uint, or float (32-bit values whose bits are reinterpreted); any other operand type — e.g. a double, long, bool, or composite constant — throws NotSupportedException naming the operand's runtime type. Only single-precision bit reinterpretation is implemented.
Solutions
- Use 32-bit operand constants (int/uint/float) for bitcasts.
- Handle 64-bit bitcasts manually by splitting into two 32-bit constants before the bitcast.
- Extend the operand switch with double/long arms (using BitConverter.DoubleToInt64Bits / partitioning into words).
Example fix
// before var bits = context.Bitcast(doubleConst, uintType); // NotSupported: operand is double // after var lo = context.Bitcast((uint)(long)doubleBitsLo, uintType); // split 64-bit into 32-bit words
Defensive patterns
Strategy: type-guard
Validate before calling
if (bitcastOperand is not (int or uint or float)) EmitRuntimeInstruction(Specification.Op.OpBitcast); // only 32-bit operands fold
Type guard
bool Is32BitOperand(object o) => o is int or uint or float;
Try / catch
try { folded = context.GetConstantValue(bitcastId); } catch (NotSupportedException ex) when (ex.Message.Contains("operand type")) { EmitRuntimeInstruction(Specification.Op.OpBitcast); } Prevention
- Use 32-bit constants for bitcasts; split 64-bit values into two words
- Convert double/half constants to float or uint before bitcasting in constant expressions
- Document which operand widths the folding path supports
When it happens
Trigger: Constant-folding an OpBitcast whose operand constant is a double/long/Half value (i.e. not a 32-bit scalar), so the operand switch's `_ =>` arm throws.
Common situations: Bitcasting double-precision constants or 64-bit integers (common in hashing/random-number shader code) on constant expressions; Half constants flowing into bitcast expressions.
Related errors
- OpBitcast result type
- OpBitcast target scalar
- Second parameter of geometry shader must be a…
- Semantic requested with type but last time with
- Unexpected type for asdouble
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/4a58725eab0e5739.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs:119
Specification.Op.OpConvertFToS => (object)(int)(float)convertOperand,
Specification.Op.OpConvertFToU => (uint)(float)convertOperand,
Specification.Op.OpConvertSToF => (float)(int)convertOperand,
Specification.Op.OpConvertUToF => (float)(uint)convertOperand,
_ => throw new NotSupportedException($"Unsupported conversion op: {op}"),
};
break;
// Bitcast: reinterpret the operand's bits as the target scalar type.
case Specification.Op.OpBitcast:
if (!TryGetConstantValue(i.Data.Memory.Span[4], out var bitcastOperand, out _))
return false;
if (ReverseTypes[resultType] is not ScalarType { Type: var bitcastTargetScalar })
throw new NotSupportedException($"OpBitcast result type {ReverseTypes[resultType]} is not a scalar");
var bitcastBits = bitcastOperand switch
{
int v => (uint)v,
uint v => v,
float v => BitConverter.SingleToUInt32Bits(v),
_ => throw new NotSupportedException($"OpBitcast operand type {bitcastOperand.GetType()} is not supported"),
};
value = bitcastTargetScalar switch
{
Scalar.Int => (object)(int)bitcastBits,
Scalar.UInt => bitcastBits,
Scalar.Float => BitConverter.UInt32BitsToSingle(bitcastBits),
_ => throw new NotSupportedException($"OpBitcast target scalar {bitcastTargetScalar} is not supported"),
};
break;
// Unary operations
case Specification.Op.OpSNegate:
case Specification.Op.OpFNegate:
if (!TryGetConstantValue(i.Data.Memory.Span[4], out var unaryOperand, out var unaryOperandTypeId))
return false;
if (unaryOperandTypeId != resultType)
return false;
value = op switch
{View on GitHub (pinned to 96fad776d2)