Expand description
The engine’s WGSL sources, assembled at compile time.
Every shader lives in crates/frust-engine/shaders/ as its own .wgsl
file and reaches Rust through include_str! — never as an inline string
literal — so the downlevel lint that scans that directory
(frust_gpu::lint::lint_wgsl_dir, driven by frust-gpu’s
downlevel_rules test) sees every line the GPU ever compiles.
§The helper prelude
The sources are ported from a WESL reference whose entry-point modules
pull shared code in with import package::helpers::.... WESL’s own
resolver is not available here — its crate family needs a newer toolchain
than this workspace’s MSRV — so the import graph is resolved two ways:
within HELPERS by hand-inlining, and between an entry-point module and
its helpers by concat!, exactly the shape frust-render’s shader-effect
VERTEX_PRELUDE uses.
Prepending the whole helper file to every entry-point module is safe
because HELPERS declares no @group/@binding global: a helper that
reads a texture takes it as a parameter. An entry-point module’s derived
bind-group layout is therefore exactly what its own bindings say, with or
without the prelude. FILTER_KERNELS is a second prelude on the same
terms, prepended to FILTER alone.
Every module the engine compiles is assembled here and nowhere else:
MODULES lists the four fixed ones, and strip_class_source derives
the strip program’s paint-class specialisations from STRIP — together
the whole list crate::gpu::pipelines::EngineShaders::register walks,
and the one the validation tests below walk.
§The paint-class pre-pass
The strip program is compiled once per PaintClass from the ONE source,
by a line-oriented string pass (specialise) rather than a second copy of
the shader: a block between a //#if FEATURE line and its //#endif line
survives only in a class that enables FEATURE (class_features), and a
//#else line inside it opens the arm that survives exactly when the //#if
arm does not. The directives are ordinary WGSL comments, which keeps the
downlevel lint (which scans shaders/) reading the real source.
§The two program families
IMAGE_SAMPLER is not a class feature but a family switch, settled per
renderer (FRUST_ENGINE_IMAGE_SAMPLER, crate::config::image_sampler_enabled):
with it, every program that keeps IMAGE — PaintClass::Image,
PaintClass::ImageFiltered and PaintClass::Uber — reads a bilinear
atlas image through one hardware-filtered textureSampleLevel; without it
they keep the manual four-textureLoad path in the feature’s //#else arm.
The sampler family is the default; the switch’s 0 is the kill switch
that selects the manual one. A renderer compiles one family, so the switch
adds no pipeline variant (strip_program_source). The manual family’s
PaintClass::Uber
program is STRIP with only the IMAGE_SAMPLER arm blanked out — line
for line the program the engine shipped before either axis existed.
A removed line is replaced by an empty one rather than dropped, so a naga
diagnostic in a specialised module names the same line number as the source
file. The pass emits only lines the source already contains, and the blocks
are placed so that dropping any combination of them leaves well-formed WGSL
(each block is a whole else if arm), so a specialisation uses no construct
the Uber program does not — the property the WebGL2 arm’s naga GLSL-ES
lowering depends on. Overrides (override constants) were the alternative
and are deliberately not used: no pipeline here sets one, and the pre-pass
needs no new pipeline-description axis to carry them.
Constants§
- CLEAR
- Region and fullscreen clears of an intermediate texture:
vs_main/vs_main_fullscreen+fs_main. - CLEAR_
NAME - The name
CLEARis registered under in the shader library. - COPY
- Rectangular region copies between textures:
vs_main+fs_main. Drawn by a backdrop blur’s region copy (a region of the frame’s own target into a pooled page — seecrate::renderer::RegionCopyMode) and, built for a swapchain’s format, by the host’s plain present copy (crate::gpu::present::CopyPresentPass). - COPY_
NAME - The name
COPYis registered under in the shader library. - DROP_
SHADOW_ KERNELS - The drop-shadow passes
FILTER’s fragment stage dispatches into beyond whatFILTER_KERNELSalready covers: the shadow’s own device-space shift, and the recolour from a blurred alpha mask into the shadow’s premultiplied colour. - FILTER
- One filter pass over one destination page:
vs_main+fs_main, one pipeline (seecrate::gpu::pipelines::EnginePipeline::Filter). - FILTER_
KERNELS - The Gaussian-blur kernels
FILTER’s fragment stage dispatches into: the two rescaling steps a decimated blur is built from, and the separable convolution run between them. - FILTER_
NAME - The name
FILTERis registered under in the shader library. - HELPERS
- Binding-free helper functions shared by every entry-point module: packing, quad geometry, extend modes, encoded-paint accessors, gradient and blur evaluation, and atlas/external image sampling.
- IMAGE_
SAMPLER - The family feature: bilinear atlas images through a hardware sampler (see the module doc’s The two program families). Kept by the image programs of the sampler family only, never by a class on its own.
- MODULES
- Every module source the engine assembles at compile time, as
(name, source)pairs — the list the validation tests walk. - STRIP
- The sparse-strip rasterizer:
vs_main+fs_main, six render-state variants (seecrate::gpu::pipelines) — and, unchanged, thePaintClass::Uberprogram every class specialisation is cut from. - STRIP_
FEATURES - The class feature names a
//#ifdirective instrip.wgslmay name —IMAGE_SAMPLER, the family switch, is the only other one. - STRIP_
NAME - The name
STRIPis registered under in the shader library.
Functions§
- class_
features - The
//#ifclass featuresclasskeeps. - samples_
images - Whether
class’s program reads atlas images at all, and so whether the sampler family specialises it withIMAGE_SAMPLER. - specialise
- Runs the feature pre-pass over
source, keeping the blocks whose feature is inenabled. - strip_
class_ name - The name the strip program specialised for
classis registered under in the shader library —STRIP_NAMEitself forPaintClass::Uber. - strip_
class_ source - The strip program of the manual family specialised for
class:STRIPwith every//#ifblock whose featureclassdoes not keep, and theIMAGE_SAMPLERarm, blanked out. - strip_
program_ features - The features
class’s program keeps in the familyimage_samplernames:class_features, plusIMAGE_SAMPLERfor an image program of the sampler family. - strip_
program_ name - The shader-library name of
class’s program in the familyimage_samplernames —strip_class_namefor every program the families share, with a suffix on the sampler family’s image programs so a library never holds two different sources under one name. - strip_
program_ source - The strip program for
classin the familyimage_samplernames:STRIPwith every blockstrip_program_featuresdoes not keep blanked out.