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"

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 vertex and fragment shaders, using SPIR-V builtin names for GPU built-in variables.

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 (SPIR-V: VertexIndex)
  • #[builtin(instance_index)] - Instance index (SPIR-V: InstanceIndex)
  • #[builtin(position)] - Output position (SPIR-V: Position)

Fragment Shader Built-ins:

  • #[builtin(frag_coord)] - Fragment coordinates (SPIR-V: FragCoord)
  • #[builtin(front_facing)] - Front-facing status (SPIR-V: FrontFacing)
  • #[builtin(frag_depth)] - Fragment depth output (SPIR-V: FragDepth)

Compute Shader Built-ins:

  • #[builtin(global_invocation_id)] - Global thread ID (SPIR-V: GlobalInvocationId)
  • #[builtin(local_invocation_id)] - Local thread ID within workgroup (SPIR-V: LocalInvocationId)

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

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)