stride3d/stride · error · NotSupportedException

Unsupported type for swizzle coalescing

Error message

Unsupported type {vectorOrScalarType} for swizzle coalescing

What it means

While coalescing consecutive swizzles (e.g. v.xy.zzz) the compiler extracts the underlying scalar/vector type to size the combined swizzle. If the operand's type is neither ScalarType nor VectorType (e.g. a matrix or other type), the switch's _ arm throws NotSupportedException.

Solutions

  1. Restructure the shader so the swizzled expression is a vector or scalar
  2. Avoid chained swizzles on non-vector types; break into intermediate variables
  3. Check the declared type of the expression being swizzled
  4. Extend the type switch in Expression.cs if you own the compiler

Example fix

// before
float x = m.xy.x; // m is a matrix
// after
float4 r = m[0];
float x = r.x;
Defensive patterns

Strategy: type-guard

Validate before calling

if (t is not (ScalarType or VectorType)) throw new InvalidOperationException($"Swizzling requires scalar/vector, got {t}");

Type guard

bool IsSwizzlable(Type t) => (t is PointerType p ? p.BaseType : t) is ScalarType or VectorType;

Try / catch

try { CoalesceSwizzles(expr); } catch (NotSupportedException e) when (e.Message.Contains("swizzle coalescing")) { FallBackToSequentialAccess(expr); }

Prevention

When it happens

Trigger: Chained swizzle access where the intermediate expression's resolved type is not scalar/vector — e.g. swizzling a matrix-typed or pointer-typed expression that isn't handled upstream.

Common situations: Shader code that double-swizzles after a matrix swizzle; type-inference producing an unexpected type; shader variants compiled with different resource types.

Related errors


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

Appendix: source

Thrown at sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs:909

            accessChainIdCount = 0;
        }

        // If current and next accessors are swizzle, combine them
        void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accessor)
        {
            if (i + 1 < Accessors.Count
                && currentValueType is PointerType { BaseType: VectorType or ScalarType } or VectorType or ScalarType
                && Accessors[i] is Identifier { Name: var swizzle1 } id1 && id1.IsVectorSwizzle()
                && Accessors[i + 1] is Identifier { Name: var swizzle2 } id2 && id2.IsVectorSwizzle())
            {
                var vectorOrScalarType = currentValueType is PointerType p ? p.BaseType : currentValueType;

                (var size, ScalarType baseType) = vectorOrScalarType switch
                {
                    ScalarType s => (1, s),
                    VectorType v => (v.Size, v.BaseType),
                    _ => throw new NotSupportedException($"Unsupported type {vectorOrScalarType} for swizzle coalescing"),
                };

                var swizzleIndices = new int[swizzle1.Length];
                for (int j = 0; j < swizzle1.Length; ++j)
                {
                    swizzleIndices[j] = ConvertSwizzle(swizzle1[j]);
                    if (swizzleIndices[j] >= size)
                        throw new InvalidOperationException($"Swizzle {Accessors[i]} is out of bound for expression {ToString(i)} of type {vectorOrScalarType}");
                }

                // Combine swizzles with previous ones
                var newSwizzleIndices = new int[swizzle2.Length];
                for (int j = 0; j < swizzle2.Length; ++j)
                {
                    newSwizzleIndices[j] = swizzleIndices[ConvertSwizzle(swizzle2[j])];
                    if (newSwizzleIndices[j] >= size)
                        throw new InvalidOperationException($"Swizzle {Accessors[i + 1]} is out of bound for expression {ToString(i)} of type {currentValueType}");
                }

View on GitHub (pinned to 96fad776d2)