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
defdeclarations 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)