stride3d/stride · error · NotSupportedException
OpBitcast result type
Error message
OpBitcast result type {ReverseTypes[resultType]} is not a scalar What it means
OpBitcast constant folding requires the bitcast's result type to be a scalar (int, uint, or float 32-bit); if ReverseTypes[resultType] is a vector, matrix, or any non-scalar type, the code throws NotSupportedException 'OpBitcast result type ... is not a scalar'. Bitcasting aggregate or non-32-bit types is not supported at compile-time fold.
Solutions
- Bitcast scalar components individually instead of the whole vector/composite constant.
- Keep the bitcast as a runtime instruction (avoid constant folding) so it executes per-component on the GPU.
- Extend the folding code to handle vector bitcasts component-wise if needed.
Example fix
// before var bits = context.GetConstantValue(context.Bitcast(f4Const, uint4Type)); // throws // after var bits = new uint4(context.GetConstantValue(Bitcast(f4.x, uintType)), ...); // per-component
Defensive patterns
Strategy: validation
Validate before calling
if (context.ReverseTypes[resultType] is not ScalarType) EmitRuntimeInstruction(Specification.Op.OpBitcast); // defer vector/composite bitcasts
Type guard
bool IsScalarBitcast(Context ctx, int resultTypeId) => ctx.ReverseTypes[resultTypeId] is ScalarType;
Try / catch
try { folded = context.GetConstantValue(bitcastId); } catch (NotSupportedException ex) when (ex.Message.Contains("is not a scalar")) { EmitRuntimeInstruction(Specification.Op.OpBitcast); } Prevention
- Bitcast scalar components individually rather than whole vectors
- Keep bit tricks out of constant-folded subexpressions
- Check the result type's kind before requesting constant folding
When it happens
Trigger: Constant-folding an OpBitcast whose result type id maps to a non-scalar type — e.g. bitcasting to vec2/vec4/ivec, a struct, or a 64-bit type — in the TryGetConstantValue bitcast case.
Common situations: Shaders bitcasting float4 to uint4 or double to uint2 on constant expressions, a common pattern for float bit inspection or hashing; generated code that moves bit tricks into constant subexpressions.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- OpBitcast operand 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/63a5a133700a272f.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs:113
case Specification.Op.OpConvertUToF:
if (!TryGetConstantValue(i.Data.Memory.Span[4], out var convertOperand, out var convertOperandTypeId))
return false;
value = op switch
{
// Note: first cast to object is important, otherwise int/float will be cast as float
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:View on GitHub (pinned to 96fad776d2)