stride3d/stride · error · NotSupportedException

Unsupported type for swizzle

Error message

Unsupported type for swizzle: {valueType}

What it means

ApplySwizzles resolves the SPIR-V type of the value being swizzled and dispatches to scalar/vector swizzle handlers. If the value's type is neither a ScalarType nor a VectorType (e.g. matrix, struct, array), the switch falls through to a NotSupportedException, because only scalar and vector components support swizzle semantics here.

Solutions

  1. Rewrite the shader to apply the swizzle only to vectors or scalars
  2. For matrices, extract a column/row vector first, then swizzle the vector
  3. Check upstream type inference to see why the value resolved to a non-scalar/vector type
  4. Extend the builder with a matrix swizzle handler if this is a supported language feature

Example fix

// before (HLSL)
float4x4 m;
float3 v = m.xyz;
// after
float4x4 m;
float3 v = m[0].xyz;
Defensive patterns

Strategy: type-guard

Validate before calling

// Ensure the swizzled expression's symbol type is scalar or vector
var t = symbolTable.ResolveType(expr.Target);
if (t is not (ScalarType or VectorType))
    throw new ShaderSemanticException($"Swizzle requires scalar/vector, got {t}");

Type guard

bool IsSwizzleable(SymbolType t) => t is ScalarType or VectorType;

Try / catch

try { var (val, sym) = ApplySwizzles(context, value, swizzle); }
catch (NotSupportedException ex) { Log.Error(ex, "Cannot swizzle value of type {Type}", context.ReverseTypes[value.TypeId]); throw; }

Prevention

When it happens

Trigger: Applying a swizzle (e.g. .xyz) to a value whose resolved type is a MatrixType, StructType, ArrayType, or StreamsType in the SPIR-V context.

Common situations: Writing HLSL with a swizzle on a matrix (mat.xy) or a sampled stream/struct value; parser/frontend passing a composite type where a vector was expected.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs:34

        var type = context.ReverseTypes[result.TypeId];
        if (type is PointerType pointerType)
        {
            type = pointerType.BaseType;
            var inst = Insert(new OpLoad(context.Types[type], context.Bound++, result.Id, null, []));
            result = new(inst.ResultId, inst.ResultType);
        }

        return result;
    }

    public (SpirvValue, SymbolType) ApplySwizzles(SpirvContext context, SpirvValue value, Span<int> swizzleIndices)
    {
        var valueType = context.ReverseTypes[value.TypeId];
        return valueType switch
        {
            ScalarType s => ApplyScalarSwizzles(context, value, s, swizzleIndices),
            VectorType v => ApplyVectorSwizzles(context, value, v, swizzleIndices),
            _ => throw new NotSupportedException($"Unsupported type for swizzle: {valueType}"),
        };
    }

    public (SpirvValue, SymbolType) ApplyScalarSwizzles(SpirvContext context, SpirvValue value, ScalarType s, Span<int> swizzleIndices)
    {
        var resultType = new VectorType(s, swizzleIndices.Length);

        Span<int> constructIndices = stackalloc int[swizzleIndices.Length];
        for (int j = 0; j < constructIndices.Length; ++j)
        {
            if (swizzleIndices[j] != 0)
                throw new InvalidOperationException("Invalid swizzle for scalar type");

            constructIndices[j] = value.Id;
        }

        SpirvValue result;
        var construct = InsertData(new OpCompositeConstruct(context.GetOrRegister(resultType), context.Bound++, new(constructIndices)));

View on GitHub (pinned to 96fad776d2)