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

Attributes

Grammar

attr ::= "vertex" | "fragment" | "compute"
         | "builtin" "(" builtin_name ")"
         | "location" "(" decimal ")"

builtin_name ::= "position" | "vertex_index" | "instance_index"
               | "front_facing" | "frag_depth" | "frag_coord"
               | "global_invocation_id" | "local_invocation_id"
               | "workgroup_id" | "num_workgroups"

Wyn supports an attribute system for shader interface specification. Attributes are written as #[attr] and can be applied to:

  • Top-level def declarations for shader identification
  • Function parameters for input interface specification
  • Return types for output interface specification

Shader Interface Attributes

Wyn uses attributes to define the interface between shader stages and the GPU pipeline.

Shader Identification

#[vertex] - Marks an entry declaration as a vertex shader entry point

#[vertex]
entry vs_main() #[builtin(position)] vec4f32 = result

#[fragment] - Marks an entry declaration as a fragment shader entry point

#[fragment]
entry fs_main() #[location(0)] vec4f32 = result

#[compute] - Marks an entry declaration as a compute shader entry point

#[compute]
entry compute_main(data: []f32) []f32 = map(|x| x * 2.0, data)

Built-in Variables

#[builtin(builtin_name)] - Maps parameters and return values to GPU built-in variables

Vertex Shader Built-ins:

  • #[builtin(vertex_index)] - Vertex index
  • #[builtin(instance_index)] - Instance index
  • #[builtin(position)] - Output position

Fragment Shader Built-ins:

  • #[builtin(frag_coord)] - Fragment coordinates
  • #[builtin(front_facing)] - Front-facing status
  • #[builtin(frag_depth)] - Fragment depth output

Compute Shader Built-ins: all four are typed vec3u32, supplying 3-D coordinates that the kernel may use as 1-D / 2-D as appropriate.

  • #[builtin(global_invocation_id)] — global thread coordinates across the whole dispatch (workgroup_id * workgroup_size + local_invocation_id)
  • #[builtin(local_invocation_id)] — thread coordinates within the enclosing workgroup
  • #[builtin(workgroup_id)] — workgroup coordinates within the dispatched grid
  • #[builtin(num_workgroups)] — total dispatched workgroup count along each axis (the value the host passed to dispatch_workgroups)

Location-based Interface

#[location(n)] - Maps parameters and return values to location-based interface variables for communication between shader stages.

#[vertex]
entry vs(
    #[builtin(vertex_index)] vid: i32,
    #[location(0)] pos: vec3f32
) #[location(1)] vec3f32 = result

#[fragment]
entry fs(
    #[location(1)] color: vec3f32
) #[location(0)] vec4f32 = result

Resource Bindings

Uniforms, storage buffers, textures, and samplers are bound to entry-point parameters via attributes (never to top-level defs).

#[uniform(set=S, binding=B)] / #[storage(set=S, binding=B, ...)] — small read-only constants / arbitrary-size buffers. See GPU Resources and Descriptor Set Layout for set-numbering rules.

#[texture(set=S, binding=B)] - binds a texture2d parameter to a sampled texture resource. set defaults to 1; binding is required.

#[sampler(set=S, binding=B)] - binds a sampler parameter to a sampler resource. set defaults to 1; binding is required.

#[fragment]
entry fs(
    #[location(0)] uv: vec2f32,
    #[texture(set=0, binding=0)] tex: texture2d,
    #[sampler(set=0, binding=1)] samp: sampler
) #[location(0)] vec4f32 =
    texture_sample(tex, samp, uv, 0.0)

See Texture and Sampler Types for the types and the texture_load / texture_sample operations.

External Linkage

#[linked("name")] — applied to an extern declaration, marks the function as resolved at SPIR-V link time. The string is the linkage name the host runtime’s linker matches against an external SPIR-V module. The Wyn compiler emits a LinkageAttributes import decoration for the function and trusts the host to supply a body with a matching Export decoration.

#[linked("sha256_compress")]
extern sha256_compress(state: [8]u32, block: [16]u32) [8]u32

The signature must match the externally-supplied function’s type exactly. WGSL emission does not support this attribute — #[linked] is SPIR-V only.

Attribute Examples

Complete Vertex Shader Interface

#[vertex]
entry vertex_main(
    #[builtin(vertex_index)] vertex_id: i32,
    #[builtin(instance_index)] instance_id: i32,
    #[location(0)] position: vec3f32,
    #[location(1)] normal: vec3f32
) #[builtin(position)] vec4f32 =
    transform_position(position, vertex_id)

Complete Fragment Shader Interface

#[fragment]
entry fragment_main(
    #[location(0)] world_pos: vec3f32,
    #[location(1)] normal: vec3f32,
    #[builtin(front_facing)] is_front: bool
) #[location(0)] vec4f32 =
    compute_color(world_pos, normal, is_front)

Complete Compute Shader Interface

#[compute]
entry process_data(
    input: []f32,
    factor: f32
) []f32 =
    map(|x| x * factor, input)