public sealed class IrradianceFieldRepairDilation and the border sync, on the device — the other half of doc 19 § L2's filler A.
No guide page documents this yet — the page shows what the code says about itself.
Remarks
Owed the moment the pool is a storage image. With PoolIsWritten set, the CPU field is no longer uploaded, so Dilate and SyncBorders repair an array nothing reads. Without these a device-filled field has a rind of unlit probes around every wall and a seam at every brick boundary — the two artefacts the whole leak-mitigation section exists to remove.
Every brick, every frame, not the fill's budget. That is what the CPU does and it is not an oversight in either: a brick the budget did not refill still has neighbours that were, and a border is a copy of a probe that may have just changed. Repairing only the refilled bricks would leave a seam that moves around the field as the round robin walks it, which is far harder to recognise than a static one. Restricting this to the dirty bricks and their neighbours is a real optimisation and is not this.
The order is fixed and each step is a dispatch with a barrier after it. Dilate, promote, then the borders coarsest first — and within each size class faces, then edges, then the corner. A border is a copy, so copying before the original is repaired copies the hole; a fine brick borrows across a size boundary by interpolating the coarse one's own field, including its border plane — so the coarse brick's borders have to be right first; and a border texel can read a border texel of its own class, so the one it reads has to belong to a dispatch that has finished. All three facts are SyncBorders's, restated as a dispatch order.
What replaces the CPU's deferred write list is a sign for the dilation, and an order for the borders. Dilate applies its repairs after the whole sweep so that a repair cannot feed the probe beside it in the same pass. A device has nowhere to put a list every invocation can also read past, so a repair is written with its validity negated — a value no filler produces and every reader already rejects, because validity <= 0 was already the test for "do not borrow from this". The promote pass flips it back. The border phase cannot use the sign — a copy needs the value, and a sign only marks one — which is why its deferral is the rank order above rather than a mark.
Fields and properties (8)
public const string ShaderNameThe shader this dispatches, in three variants.
public EffectSystem? EffectsWhere the repair variants are resolved from. Null dispatches nothing.
public ComputePipelineCache? PipelinesWhere the compute pipelines come from. Null dispatches nothing.
public DescriptorAllocator? DescriptorsWhere the descriptor sets come from. Null dispatches nothing.
public ParameterCollection ParametersWhere the field is, by the names the reflection interned.
public int DilationPassesHow far a repair may travel into invalid probes, in probes.
public int DispatchesHow many dispatches the last repair recorded, or zero when it recorded none.
public string? SkippedWhy the last call recorded nothing, or null when it recorded something.
Methods (3)
public IrradianceFieldRepair(IGraphicsDevice device)Creates a repair on a device. Nothing is allocated until the first dispatch.
public int Record(ICommandList commands, IrradianceField field, IrradianceFieldTexture texture)Records the dilation and the border sync over every brick of a field.
public void Dispose()Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
Used by (2)
- IrradianceFieldFillVixen.Rendering
- IrradianceRepairDeviceTestsVixen.Graphics.Golden.Tests