public sealed class UploadBuffer<T> where T : unmanagedOne frame's worth of unmanaged records in a storage buffer, addressed by index.
No guide page documents this yet — the page shows what the code says about itself.
Remarks
Shared by skinning, instancing and the clustered light path, which want the same thing: a run of records written once a frame and indexed by a shader. A storage buffer rather than a uniform block because all three overrun a uniform block's guaranteed 16 KB immediately — that is 256 matrices, which is one skeleton or one small crowd.
Indices, not offsets. Callers get the index of their first record and the shader indexes the array, so nothing here has to know about minStorageBufferOffsetAlignment and no run is padded up to it. The features then get the index to the shader by different routes — a push constant for skinning, the draw call's own firstInstance for instancing, and nothing at all for a light list every fragment reads whole.
Refilled from scratch every frame. Retaining ranges across frames would mean tracking which objects changed and compacting the holes left by the ones that went away, which is a defragmenter in the frame path to save writing a few thousand matrices a host already had to compute.
One region per frame in flight, and the caller binds at Offset. Writing the same bytes every frame is a race the API cannot report: Write on a host-visible buffer is a memcpy into memory the GPU may still be reading for a frame that has not finished, and the symptom is a skeleton or an instance list that is briefly a blend of two frames. The ring is the same one DescriptorAllocator uses and for the same reason, and it is offsets rather than shifted indices so that nothing downstream — a shader indexing from zero, a push-constant base, a firstInstance — has to know the ring exists.
Fields and properties (9)
public IGraphicsDevice? DeviceThe device the buffer lives on. Set before the first upload.
public BufferHandle BufferThe buffer, valid once something has been added and uploaded.
public int CountHow many records this frame holds.
public int CapacityHow many the buffer has room for, per frame in flight.
public long OffsetWhere this frame's region starts, in bytes. Bind the buffer at this offset.
public long StrideHow many bytes one frame's region occupies, including its alignment padding.
public int SlotsHow many frames the ring is deep.
public int AlignmentWhat a buffer binding's offset must be a multiple of.
public ReadOnlySpan<T> ItemsWhat has been written this frame, for a test or an inspector.
Methods (5)
public UploadBuffer(string name, BufferUsage usage = Storage)One frame's worth of unmanaged records in a storage buffer, addressed by index.
public void Begin()Starts a frame: moves to the next region and forgets the last one's contents.
public int Add(ReadOnlySpan<T> items)Appends a run and returns the index of its first matrix.
public void Upload()Writes this frame's records to the device.
public void Dispose()Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
Used by (18)
- BufferUploadRendererVixen.Rendering
- ForwardLightingRenderFeatureVixen.Rendering
- GpuClusterVisibilityVixen.Rendering
- GpuDrawArgumentsVixen.Rendering
- GpuVisibilityGroupVixen.Rendering
- InstancingRenderFeatureVixen.Rendering
- IrradianceFieldFillVixen.Rendering
- IrradianceFieldRepairVixen.Rendering
- ParticleRenderFeatureVixen.Rendering
- PunctualShadowRendererVixen.Rendering
- ScreenProbeAccumulateFillVixen.Rendering
- ScreenProbeResolveVixen.Rendering
- ScreenProbeTraceFillVixen.Rendering
- SkinningAndInstancingTestsVixen.Rendering.Tests
- SkinningRenderFeatureVixen.Rendering
- SpriteRenderFeatureVixen.Rendering
- TransformRenderFeatureVixen.Rendering
- VirtualShadowAtlasVixen.Rendering