Skip to content

Commit 817df78

Browse files
Document staged probe constraints
1 parent 36eef59 commit 817df78

1 file changed

Lines changed: 13 additions & 0 deletions

File tree

src/ImageSharp.Drawing.WebGPU/WebGPURuntime.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,8 @@ void Callback(WGPUMapAsyncStatus status, void* userData)
669669
/// </remarks>
670670
private static bool ProbeComputeDispatch(WebGPU api, WGPUDeviceImpl* device, WGPUQueueImpl* queue)
671671
{
672+
// The chunk-reset shader's single binding is one bump-allocators block, so the storage
673+
// buffer must be exactly that size for the bind-group layout's minimum binding size.
672674
nuint statusByteCount = (nuint)sizeof(GpuSceneBumpAllocators);
673675

674676
WGPUBufferImpl* storageBuffer = null;
@@ -696,6 +698,8 @@ private static bool ProbeComputeDispatch(WebGPU api, WGPUDeviceImpl* device, WGP
696698
mappedAtCreation = 0U,
697699
};
698700

701+
// The shader writes the storage buffer, the copy drains it into the mappable
702+
// readback buffer, and the map proves the whole chain executed on the adapter.
699703
storageBuffer = api.DeviceCreateBuffer(device, in storageDescriptor);
700704
readbackBuffer = api.DeviceCreateBuffer(device, in readbackDescriptor);
701705
if (storageBuffer is null || readbackBuffer is null)
@@ -756,6 +760,7 @@ private static bool ProbeComputeDispatch(WebGPU api, WGPUDeviceImpl* device, WGP
756760
}
757761
}
758762

763+
// Bind-group creation copies the entries during the call, so stack storage is safe.
759764
WGPUBindGroupEntry* bindEntries = stackalloc WGPUBindGroupEntry[1];
760765
bindEntries[0] = new WGPUBindGroupEntry
761766
{
@@ -792,12 +797,16 @@ private static bool ProbeComputeDispatch(WebGPU api, WGPUDeviceImpl* device, WGP
792797
return false;
793798
}
794799

800+
// The pass must be ended and released before the encoder can record the copy;
801+
// an open pass makes every later encoder command invalid.
795802
api.ComputePassEncoderSetPipeline(pass, pipeline);
796803
api.ComputePassEncoderSetBindGroup(pass, 0, bindGroup, 0, null);
797804
api.ComputePassEncoderDispatchWorkgroups(pass, ChunkResetComputeShader.GetDispatchX(), 1, 1);
798805
api.ComputePassEncoderEnd(pass);
799806
api.ComputePassEncoderRelease(pass);
800807

808+
// Queue ordering guarantees the dispatch's writes are visible to the copy inside
809+
// the same submission, so no host-side synchronization sits between them.
801810
api.CommandEncoderCopyBufferToBuffer(commandEncoder, storageBuffer, 0, readbackBuffer, 0, statusByteCount);
802811

803812
WGPUCommandBufferDescriptor commandBufferDescriptor = default;
@@ -812,6 +821,7 @@ private static bool ProbeComputeDispatch(WebGPU api, WGPUDeviceImpl* device, WGP
812821
}
813822
finally
814823
{
824+
// Releases run in reverse creation order so no object outlives one it references.
815825
if (commandBuffer is not null)
816826
{
817827
api.CommandBufferRelease(commandBuffer);
@@ -875,6 +885,9 @@ private static bool ProbeSceneRenderReadback()
875885
DrawingBackendScene? scene = null;
876886
try
877887
{
888+
// A fill plus a blended layer is the smallest scene that records a layer
889+
// boundary into the retained command stream, so its replay drives the full
890+
// scheduling, fine, and composition pipeline the renderer uses.
878891
using (WebGPURenderTarget sceneTarget = new(16, 16))
879892
using (DrawingCanvas sceneCanvas = sceneTarget.CreateCanvas())
880893
{

0 commit comments

Comments
 (0)