Skip to content

Return SubmitResult from Queue::submit() instead of blocking#1101

Draft
MarijnS95 wants to merge 3 commits intollvm:mainfrom
Traverse-Research:in-flight-command-buffers
Draft

Return SubmitResult from Queue::submit() instead of blocking#1101
MarijnS95 wants to merge 3 commits intollvm:mainfrom
Traverse-Research:in-flight-command-buffers

Conversation

@MarijnS95
Copy link
Copy Markdown
Collaborator

@MarijnS95 MarijnS95 commented Apr 17, 2026

Depends on #1057

Change Queue::submit() to return Expected<SubmitResult> (a fence + signal value pair) instead of blocking until completion. Each backend (Vulkan, DirectX, Metal) now returns its queue fence and counter value, and callers explicitly wait via SubmitResult::waitForCompletion() before reading back results.

This allows command buffers submitted between the first and last submit to remain in-flight on the GPU without host-side synchronization.

  • Vulkan: cleanup() waits on the queue fence for error-path safety
  • DirectX: tile mapping sync reuses the queue's SubmitFence
  • Metal: MTLQueue gains a SharedEvent fence; the last command buffer in each batch encodes a signal on it

🤖 Generated with Claude Code

@MarijnS95 MarijnS95 force-pushed the in-flight-command-buffers branch from a57700f to fafbd2e Compare April 20, 2026 13:20
Move command buffer submission logic from each backend's Device into
Queue::submit(), which takes ownership of the command buffers. Each
backend uses its Fence abstraction for GPU synchronization:

- Metal: commit() + waitUntilCompleted()
- Vulkan: vkQueueSubmit() signaling a timeline semaphore (VulkanFence),
  then VulkanFence::waitForCompletion()
- DX12: ExecuteCommandLists() + Queue::Signal() on the queue-owned
  DXFence, then DXFence::waitForCompletion()

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@MarijnS95 MarijnS95 force-pushed the in-flight-command-buffers branch from fafbd2e to 3f84c18 Compare April 20, 2026 13:50
Change `Queue::submit()` to return `Expected<SubmitResult>` (a fence +
signal value pair) instead of blocking until completion.  Each backend
(Vulkan, DirectX, Metal) now returns its queue fence and counter value,
and callers explicitly wait via `SubmitResult::waitForCompletion()`
before reading back results.

This allows command buffers submitted between the first and last submit
to remain in-flight on the GPU without host-side synchronization.

- Vulkan: `cleanup()` waits on the queue fence for error-path safety
- DirectX: tile mapping sync reuses the queue's `SubmitFence`
- Metal: `MTLQueue` gains a `SharedEvent` fence; the last command buffer
  in each batch encodes a signal on it

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@MarijnS95 MarijnS95 force-pushed the in-flight-command-buffers branch from 3f84c18 to b1b3f4e Compare April 20, 2026 13:58
Queue::submit() takes ownership of command buffers, but their destructors
free backend resources (VkCommandPool, ID3D12CommandAllocator) that the
GPU may still be reading from.  Track in-flight batches per queue, tagged
with their fence signal value, and non-blockingly query fence progress at
the start of each submit to release completed batches.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@MarijnS95 MarijnS95 force-pushed the in-flight-command-buffers branch from 9b4fc60 to 2f5662a Compare April 21, 2026 07:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant