Skip to main content

Module pipelines

Module pipelines 

Source
Expand description

The nine render pipelines the engine draws with, as plain values.

Six of them rasterize sparse strips out of the one strip.wgsl program, differing only in their render state; two more clear and copy intermediate textures, and the last runs one pass of a layer filter. Each is described by a frust_gpu::RenderPipelineDesc — a value holding no GPU handle — so the whole set can be listed at start-up and handed to frust_gpu::PipelineCache::warm_up before the first frame asks for one. That is the substrate’s stated contract: a frame is never the first place a pipeline gets compiled.

§The six strip variants

VariantTargetBlendDepth
EnginePipeline::StripIntermediateINTERMEDIATE_FORMATpremultipliednone
EnginePipeline::StripAlphathe frame’s target formatpremultipliednone
EnginePipeline::StripDepthAlphathe frame’s target formatpremultipliedtest, no write
EnginePipeline::StripOpaquethe frame’s target formatnonetest and write
EnginePipeline::StripDestOutthe frame’s target formatDEST_OUT_BLENDnone
EnginePipeline::StripDepthDestOutthe frame’s target formatDEST_OUT_BLENDtest, no write

The depth comparison is wgpu::CompareFunction::LessEqual against a DEPTH_FORMAT attachment, which is what the vertex stage’s own z encoding expects: strip.wgsl maps painter’s-order index 0 (the backmost draw) to z = 1.0 and each draw in front of it to a smaller z, so drawing front-to-back lets the opaque pass reject everything already covered.

§The atlas-layer target

A pass that rasterizes glyph outlines into one layer of the atlas array draws through ATLAS_STRIP_PIPELINE, which is EnginePipeline::StripIntermediate itself rather than a variant of its own. An atlas layer is an crate::gpu::atlas::ATLAS_FORMAT colour target with no depth attachment, composited source-over so a COLR glyph’s layers and a re-used slot’s clear stack in the order they were recorded — which is the render state StripIntermediate already is, field for field. A second enum arm carrying identical state would compile a second identical pipeline object, and would break the_warm_up_list_covers_every_pipeline_exactly_once, whose whole point is that no two arms describe the same pipeline. What the atlas target gets instead is a name and [the_atlas_target_reuses_the_intermediate_variant], which pins the format equality the reuse rests on: if either format is ever moved, that test fails rather than glyphs quietly rendering through a pipeline whose colour target no longer matches its attachment.

§The destination-out pair

The hole punch crate::compile::clear lowers is a strip run like any other — same program, same instance layout — and differs only in its blend state, which is why it is a pipeline variant rather than a shader of its own. DEST_OUT_BLEND computes dst · (1 − src.a) in fixed function, for the colour and the alpha component, which is what erases a rectangle to (0, 0, 0, 0) without a shader-side composite reading a target it is also writing.

There are two of them for the same reason there are two alpha variants: a pipeline’s depth state has to agree with whether the pass it runs in attaches a depth buffer at all, and the engine’s depth attachment is optional (no attachment, or FRUST_ENGINE_NO_DEPTH). The depth-testing one is what restores the paint order the display list recorded; the other is the same trade the two draw passes already make when they collapse into one.

§The filter pass

EnginePipeline::Filter is a genuinely new pipeline rather than a second name for an existing one: a different program (filter.wgsl), a different instance layout (filter_vertex_layout, eight words per instance against the strip’s six), and a different bind-group shape. It writes INTERMEDIATE_FORMAT unblended and with no depth, because a filter pass replaces the region it writes rather than compositing onto it — the scheduler clears the destination page ahead of every filter round, and the quad overdraws a transparent padding border around the region for the same reason (see crate::schedule’s Filter rounds).

It is also where the engine’s first sampler appears. Every other pipeline reads its textures with textureLoad at integer coordinates; the blur kernels sample bilinearly at fractional offsets, which is what lets a decimation cost four samples instead of sixteen and a convolution tap one instead of two. The sampler itself is crate::gpu::targets::filter_sampler — the layout here only has to know that group 1 carries a texture and a sampler.

§Bind groups

frust_gpu::RenderPipelineDesc has no explicit-layout axis: every pipeline uses wgpu’s default layout, derived from the shader module. The group structure is therefore whatever the WGSL declares, and it matches the reference renderer’s explicit layouts group for group — strip programs bind groups 0..3 (alphas + config + layer input; atlas array + external texture; encoded paints; gradient LUT), which is the WebGL2 ceiling of four exactly, with no headroom. The filter program binds two (the filter-data texture; the source page plus its sampler), well inside it. EnginePipeline::layout_desc restates each pipeline’s shape as the value frust_gpu::lint::lint_pipeline_layout checks, so that ceiling is a test rather than a comment.

Structs§

EngineShaders
The engine’s compiled shader modules, by id.

Enums§

EnginePipeline
One of the engine’s render pipelines.
EngineShaderModule
Which of the four registered modules a pipeline draws with.

Constants§

ATLAS_STRIP_PIPELINE
The strip pipeline a pass whose colour attachment is one atlas array layer draws through.
DEPTH_FORMAT
The depth attachment format the depth-testing strip variants use.
DEST_OUT_BLEND
The fixed-function destination-out blend the punch pass draws with.
FS_MAIN
Fragment entry point of every program here.
INTERMEDIATE_FORMAT
The format every intermediate (off-screen) strip target uses.
TOPOLOGY
Every strip instance expands to one quad, so every pipeline here draws a four-vertex strip with no index buffer.
VS_MAIN
Vertex entry point of the strip, clear (region) and copy programs alike.
VS_MAIN_FULLSCREEN
Vertex entry point of the scissor-driven atlas clear.

Functions§

atlas_strip_desc
The description ATLAS_STRIP_PIPELINE is built from.
clear_vertex_layout
The clear program’s instance layout: origin, size and target size, each a pair of u32s, 24 bytes per instance.
copy_vertex_layout
The copy program’s instance layout: destination origin, source origin, region size and destination size, each a u16 pair packed into one u32, 16 bytes per instance.
filter_vertex_layout
The filter program’s instance layout: two u16-pair extents each for the source region, the destination region and the destination page, plus the filter’s own texel offset, the layer’s unscaled extent and the pass kind — eight u32s, 32 bytes per instance.
warm_up
Queues every engine pipeline for background compilation.
warm_up_descs
The full warm-up list: every pipeline in EnginePipeline::ALL, described against target_format.