backend library

The shader contract a backend is written against (D27): what the engine's stages bind, how the engine's uniform blocks are laid out, how a backend compiles the material language, and the check that a pipeline's stages agree.

For a backend's author, inside this repository or outside it. A fifth backend — Vulkan or Metal through FFI, Direct3D, a headless server renderer — reads here:

  • stageBindings: the uniform blocks and samplers each of the engine's stages keeps once compiled, which a draw through it must bind and may bind — the table every in-repo backend binds by;
  • uniformBlocks: every uniform block's members, offsets and sizes as the compiler laid them out (std140);
  • MaterialCompiler and MaterialCompilerRegistry: how the backend turns a .f3dmat source into its section of a shader bundle, for the build hook and for RuntimeShaders alike (D26);
  • ShaderTarget and compileStage (package:flutter3d_shaders/compile.dart, which needs glslang and naga on the machine): a stage's SPIR-V and its text in the backend's language;
  • MaterialStageBudget: the textures, samplers and uniform blocks one stage may bind, the engine's and a material's together;
  • StageInterface and checkStageAgreement: the varyings, attributes and blocks two stages of a pipeline must agree on.

The entry points the engine asks a bundle for are requiredShaders and computeShaders in package:flutter3d_shaders/flutter3d_shaders.dart; the F3D_* defines the engine's GLSL is compiled with, and the bindings a plugin's lit model adds, are written down in docs/CONTRACTS.md ("The shader ABI").

What changes in a minor. The tables follow the shaders: a stage that gains a sampler or a block that gains a member changes them in any release, and a backend that binds by the tables follows without a code change. The types here are the contract and only grow.

Classes

GlslBindingCount
What countGlslBindings counts in one stage's GLSL: a class rather than a record, so a later minor can count one more kind of binding.
MaterialCompiler
How one backend turns a .f3dmat source into its section of a material's shader bundle (D26).
MaterialCompileRequest
What a MaterialCompiler is asked to compile: one growing object, so a later minor that hands a compiler something more adds a member here and breaks no compiler.
MaterialCompileResult
What a MaterialCompiler made of a MaterialCompileRequest: its bundle section's bytes.
MaterialCompilerRegistry
The material compilers of one build or one engine, by backend.
MaterialStageBudget
The textures, samplers and uniform blocks one stage of a pipeline may bind, the engine's own bindings and a material's together (M3).
MaterialStageSource
One stage a .f3dmat source becomes, as GLSL the engine's emitter wrote: the fragment stage, and a vertex block's two vertex stages.
ShaderTarget
What a stage's SPIR-V is translated into for a backend: WGSL for WebGPU, Metal's shading language, HLSL, a GLSL dialect, or nothing — the SPIR-V itself, for a backend that loads it (Vulkan).
StageBlockMember
One member of a uniform block, in the order the block declares it.
StageInterface
What one stage of a pipeline declares at its edges: what comes in, what goes out, and the uniform blocks it reads.
StageMismatch
One way two stages of a pipeline disagree, with the names a person fixes it by.
StageMismatchKind
What kind of disagreement a StageMismatch is.
StageVariable
One variable a stage reads or writes across its boundary: a vertex attribute, a varying, a fragment output.

Constants

stageBindings → const Map<String, StageBindings>
uniformBlocks → const Map<String, Map<String, Map<String, UniformMemberLayout>>>

Functions

checkBundleAgreement({required Map<String, String> vertex, required Map<String, String> fragment}) → List<StageMismatch>
Every mismatch between the stages of a bundle that are drawn together: vertex and fragment are the GLSL of each stage by name, includes resolved, and each vertex stage is held to the fragment stage pairedFragmentStage names. Empty when they agree.
checkStageAgreement({required StageInterface vertex, required StageInterface fragment, List<StageVariable>? attributes}) → List<StageMismatch>
Whether vertex and fragment, the stages of one pipeline, agree — and with attributes, the vertex layout the pipeline is drawn with, when it is known. Every mismatch, in the order found; empty when they agree.
countGlslBindings(String glsl, {Set<String> defines = const <String>{}}) → GlslBindingCount
The distinct textures and uniform blocks glsl declares (its includes already resolved), after #define, #undef, #ifdef, #ifndef, #else and #endif are applied with defines set to begin with. A directive it does not read (#if <expression>) is taken as true, which counts more rather than fewer.
pairedFragmentStage(String vertex, Set<String> fragments) → String?
The fragment stage of fragments that the vertex stage vertex is drawn with in a bundle, by the names the material language and the engine give their stages, or null when its name pairs it with none.
requireBundleAgreement({required Map<String, String> vertex, required Map<String, String> fragment}) → void
Throws a StageAgreementException when checkBundleAgreement finds anything: what a bundle's section writer calls before it writes.

Exceptions / Errors

MaterialCompileException
A compiler that cannot compile what it was asked, with the sentence that says why and what to do instead.
StageAgreementException
A bundle the writer refused because the stages of one of its pipelines disagree: every StageMismatch found, each naming both stages.