Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

SPIR-V Compatibility Types

In addition to arrays, Wyn provides vector types that directly correspond to SPIR-V/GLSL types. These are distinct types optimized for GPU operations and are required for certain shader interfaces and built-in variables.

Vector Types

Wyn supports vector types using the naming convention vecNT where:

  • N is the number of components (2, 3, or 4)
  • T is the element type (i32, f32, etc.)

Common vector types:

Component Type2-component3-component4-component
i32 (signed)vec2i32vec3i32vec4i32
f32 (32-bit float)vec2f32vec3f32vec4f32

Vector types are distinct from array types and have different semantics:

  • Vectors are fixed-size, optimized for SIMD operations
  • Arrays are more general containers with runtime length operations

Example usage:

-- Vector types for graphics operations (using @[...] literal syntax)
let position: vec3f32 = @[1.0, 2.0, 3.0]
let color: vec4f32 = @[1.0, 0.0, 0.0, 1.0]

-- Alternative: explicit constructor syntax
let pos2: vec3f32 = vec3 1.0f32 2.0f32 3.0f32

-- Built-in variables often require vector types
#[vertex]
entry vertex_main() #[builtin(position)] vec4f32 =
  @[0.0, 0.0, 0.0, 1.0]

Vector Swizzles

A vector’s components are accessed with field syntax (v.x). Wyn supports WGSL-style swizzles: one to four letters drawn from a single “swizzle set”. The two sets and their component indices are:

Set0123
xyzwxyzw
rgbargba

rgba is an alias set for xyzw (r == x, g == y, b == z, a == w) — the two sets address the same underlying components and produce identical values. Mixing letters from the two sets in one swizzle (.xg, .rbw) is a type error.

A single-letter swizzle produces the scalar component; a 2-, 3-, or 4-letter swizzle produces a new vector of that length. Letters may repeat and may be in any order.

Each referenced component must lie within the source vector’s length — .z (or .b) on a vec2 is a type error.

let v: vec4f32 = @[1.0, 2.0, 3.0, 4.0]
let first: f32       = v.x        -- 1.0
let alpha: f32       = v.a        -- 4.0   (same as v.w)
let rgb:   vec3f32   = v.rgb      -- (1.0, 2.0, 3.0)
let rev:   vec4f32   = v.wzyx     -- (4.0, 3.0, 2.0, 1.0)
let splat: vec3f32   = v.xxx      -- (1.0, 1.0, 1.0)

Vector Constructors

Vectors can be constructed in two ways:

1. Literal syntax (@[...]) - Preferred for most cases:

let v1: vec3f32 = @[1.0, 2.0, 3.0]
let v2: vec4f32 = @[1.0, 0.0, 0.0, 1.0]

2. Explicit constructor syntax (vecN) - Useful when type suffix is needed:

let v1: vec3f32 = vec3 1.0f32 2.0f32 3.0f32
let v2: vec4f32 = vec4 1.0f32 2.0f32 3.0f32 4.0f32

The element type is inferred from the arguments or the context.

Implementation Details

  • Attributes are parsed directly into SPIR-V enum values for type safety
  • Built-in names follow SPIR-V specification (e.g., VertexIndex, Position)
  • Location numbers must be non-negative integers
  • Each shader stage has specific allowed built-ins
  • The compiler automatically generates appropriate SPIR-V decorations

Type Safety

The attribute system is statically type-checked:

  • Built-in attributes must be applied to compatible types
  • Location attributes can be used with any serializable type
  • Shader stage compatibility is verified at compile time
  • Interface matching between vertex and fragment shaders is validated