Vixen
02b45cc4
csharp
public sealed class GpuClusterSoftwareRaster

Phase 6: the clusters the traversal thought too small for the hardware, rasterized in compute.

No guide page documents this yet — the page shows what the code says about itself.

Remarks

An accelerator and not a path. A hardware rasterizer shades in quads, so a triangle covering less than one wastes roughly four fifths of the fragments it launches — and a virtualized cut is chosen to put a cluster's error under a pixel, which is exactly the regime where that happens. Above a few pixels a triangle the fixed-function path wins by a lot, which is why the routing threshold is a number a host measures and why zero is its default. docs/plan/22-virtualized-geometry.md phase 6 says as much: gated on a measurement, not on a plan.

Capability-gated, and the gate is upstream of this class. Resolving which surface is nearest without a depth attachment means a 64-bit atomicMax, which is optional on Vulkan, SM6.6 on D3D12 and absent from WebGPU. GpuClusterVisibility forces every view's threshold to zero on a device without HasInt64Atomics, so the traversal routes nothing here and this records nothing — one answer to "is the software path on", rather than two that have to agree.

Two dispatches, and the second is what makes one picture. The raster resolves among itself in a packed depth-above-identity buffer, because a compute pass cannot write the depth attachment the hardware raster used. The merge then asks, per pixel, whether what it found is nearer than what that draw left behind — so the ordering between the two rasters comes out of a real depth comparison rather than out of which one ran last. It also clears the packed buffer as it reads it, which is the whole cost of clearing it: a screen of 64-bit words is sixteen megabytes at 1080p, and copying that in every frame would cost more than the raster it serves.

⚠ It must be recorded after the hardware raster's render pass and before the binning. The first because it reads that pass's depth and overwrites its identities; the second because GpuVisibilityTiles bins what is in the identity buffer. Nothing here can check either — an open command list does not say what has been recorded into it — which is why VisibilityBufferRenderer owns the ordering, exactly as it owns the binning's.

Fields and properties (11)

  • public const int MergeGroupSize

    How many pixels one merge workgroup covers.

  • public const float DepthScale

    What a depth is multiplied by to become the top half of the packed word.

  • public const int PixelBytes

    How many bytes one pixel of the packed buffer occupies.

  • public EffectSystem? Effects

    Where the two variants are resolved from. Null does nothing.

  • public ComputePipelineCache? Pipelines

    Where the compute pipelines come from. Null does nothing.

  • public GpuClusterVisibility? Visibility

    The traversal whose software-routed clusters to draw. Null does nothing.

  • public MeshletPagePool? Pages

    The pool the geometry is read out of. Null does nothing.

  • public bool Supported

    Whether this device can run the software raster at all.

  • public bool Rastered

    Whether the last Record dispatched the raster and the merge.

  • public Int2 Size

    How many pixels the packed buffer currently covers.

  • public static string MergeKey

    The permutation selecting the merge.

Methods (8)

  • public static ulong Key(float depth, uint identity)

    One pixel's depth and identity as the word an atomicMax resolves.

  • public static float DepthOf(ulong key)

    The depth a key carries, back in the range a depth buffer holds.

  • public static uint IdentityOf(ulong key)

    The identity it carries.

  • public GpuClusterSoftwareRaster(IGraphicsDevice device)

    Creates a software raster that runs on a device.

  • public static EffectKey Key(bool merge)

    The effect key selecting one of the two variants.

  • public bool Record(ICommandList list, TextureViewHandle identities, TextureViewHandle depth, in Matrix4x4 viewProjection, Int2 size)

    Records the raster and the merge that lands it.

  • public bool Prepare(ICommandList list)

    Copies the y and z extents into the argument buffer, once.

  • public void Dispose()

    Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.

Used by (6)

  • ClusterCullingRendererVixen.Rendering
  • CompositorBuilderVixen.Rendering
  • SoftwareRasterVixen.Rendering
  • SoftwareRasterTestsVixen.Rendering.Tests
  • VirtualGeometrySystemVixen.Rendering
  • VisibilityBufferRendererVixen.Rendering