Language1 min read

The Pass

How a BWSL pass groups shader stages, attributes, helper functions, and stage composition rules.

Reading Time
1 min
Word Count
135
Sections
7
Try It Live

Pressure-test the syntax

Take the concept from this page into the playground and deliberately break a pass, binding, or type signature to see how the compiler responds.

Try a Live Edit

A pass is the unit of compilation inside a pipeline. Each pass is either:

  • a graphics pass with vertex and optional fragment
  • a compute pass with one compute block

Graphics Passes

bwsl
pass "Main" {
use attributes { position, texcoord }
vertex {
output.position = float4(attributes.position, 1.0);
output.uv = attributes.texcoord;
}
fragment {
output.color = float4(input.uv, 0.0, 1.0);
}
}

Notes:

  • use attributes { ... } is only valid on graphics passes
  • the vertex stage must write output.position
  • the fragment stage is optional

Compute Passes

bwsl
pass "Simulate" {
compute "Main" [64, 1, 1] {
uint3 gid = input.global_id;
}
}

Rules enforced by the parser:

  • a pass cannot combine compute with vertex or fragment
  • only one compute block is allowed per pass
  • compute passes cannot use use attributes

Pass-Scoped Functions

Helper functions can live inside a pass and are only visible there:

bwsl
pass "Main" {
use attributes { position }
offsetPos :: (float3 p) -> float3 {
return p + float3(0.0, 0.1, 0.0);
}
vertex {
output.position = float4(offsetPos(attributes.position), 1.0);
}
}

Stage Assignment

Pass stages can be declared inline or assigned from expressions that resolve to stage-returning helper functions.

Inline:

bwsl
pass "Main" {
use attributes { position }
vertex {
output.position = float4(attributes.position, 1.0);
}
}

Assigned:

bwsl
vertexFunc :: () -> vertex_function {
vertex {
output.position = float4(0.0, 0.0, 1.0, 1.0);
}
}
pass "Main" {
use attributes { position }
vertex = vertexFunc()
}

Stage Reuse

You can reuse a stage from another pass:

bwsl
pass "Base" {
use attributes { position }
vertex {
output.position = float4(attributes.position, 1.0);
}
}
pass "Reuse" {
use attributes { position }
vertex = "Base".vertex
}

Depth-Only Passes

Depth-only graphics passes can disable fragment output explicitly:

bwsl
pass "Shadow" {
use attributes { position }
vertex {
output.position = float4(attributes.position, 1.0);
}
fragment = null
}