Skip to content

Implement an abstract Fence type to expose waiting for command buffer completion.#1007

Open
manon-traverse wants to merge 3 commits intollvm:mainfrom
Traverse-Research:render-backend-api-fence
Open

Implement an abstract Fence type to expose waiting for command buffer completion.#1007
manon-traverse wants to merge 3 commits intollvm:mainfrom
Traverse-Research:render-backend-api-fence

Conversation

@manon-traverse
Copy link
Copy Markdown
Contributor

@manon-traverse manon-traverse commented Mar 24, 2026

The Fence type is modeled around the DX12 Fence. The closest equivalent in Vulkan is a Timeline Semaphore. These are widely supported and included in Vulkan 1.2. Metal provides the same functionality through the SharedEvent type.

The abstract interface allows us to wait for GPU work to complete by waiting on a signal value using:

Fence->waitForCompletion(SignalValue);

Signaling the value still requires downcasting because queue submission is not done via an abstract interface yet.

@damyanp
Copy link
Copy Markdown
Contributor

damyanp commented Mar 26, 2026

@manon-traverse - is this Ready for review?

@MarijnS95
Copy link
Copy Markdown
Contributor

#987 was merged, is it time to rebase this?

@manon-traverse
Copy link
Copy Markdown
Contributor Author

@manon-traverse - is this Ready for review?

@damyanp No it's mainly waiting for the metal-cpp update PR to get merged in: #1004

@manon-traverse manon-traverse force-pushed the render-backend-api-fence branch from bcf1180 to 41f208f Compare March 31, 2026 19:39
@manon-traverse manon-traverse marked this pull request as ready for review March 31, 2026 19:40
Copy link
Copy Markdown
Contributor

@damyanp damyanp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's hard to convince myself this is the right abstraction since I don't think anything is actually using the abstraction - as far as I can tell, there isn't anything actually using the fence through the Fence interface?

@manon-traverse
Copy link
Copy Markdown
Contributor Author

It's hard to convince myself this is the right abstraction since I don't think anything is actually using the abstraction - as far as I can tell, there isn't anything actually using the fence through the Fence interface?

The abstract is being used. However it is just being used for waiting for work completion by waiting on the signal value. Once @MarijnS95's work on command buffer submission on the queue is completed the Fence will be signaled by that function.

Currently, the API-agnostic and API-specific code is fairly intertwined. As we get more of the graphics APIs covered in the API agnostic code this will become less of a problem.

MarijnS95 added a commit to Traverse-Research/offload-test-suite that referenced this pull request Apr 1, 2026
Move command buffer submission logic from each backend's Device into
Queue::submit(), which takes ownership of the command buffers. For now
it blocks internally until completion; a TODO marks that it will return
a Fence once the Fence abstraction from PR llvm#1007 is available.

- Metal: commit + waitUntilCompleted + error check
- Vulkan: vkEndCommandBuffer + temporary fence + vkQueueSubmit + wait
- DX12: CmdList Close + ExecuteCommandLists + fence signal/wait

VulkanQueue now stores a VkDevice handle (with a TODO for lifetime
management) so it can create/destroy fences independently.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
MarijnS95 added a commit to Traverse-Research/offload-test-suite that referenced this pull request Apr 2, 2026
Move command buffer submission logic from each backend's Device into
Queue::submit(), which takes ownership of the command buffers. For now
it blocks internally until completion; a TODO marks that it will return
a Fence once the Fence abstraction from PR llvm#1007 is available.

- Metal: commit + waitUntilCompleted + error check
- Vulkan: vkEndCommandBuffer + temporary fence + vkQueueSubmit + wait
- DX12: CmdList Close + ExecuteCommandLists + fence signal/wait

VulkanQueue now stores a VkDevice handle (with a TODO for lifetime
management) so it can create/destroy fences independently.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
MarijnS95 added a commit to Traverse-Research/offload-test-suite that referenced this pull request Apr 2, 2026
Move command buffer submission logic from each backend's Device into
Queue::submit(), which takes ownership of the command buffers. For now
it blocks internally until completion; a TODO marks that it will return
a Fence once the Fence abstraction from PR llvm#1007 is available.

- Metal: commit + waitUntilCompleted + error check
- Vulkan: vkEndCommandBuffer + temporary fence + vkQueueSubmit + wait
- DX12: CmdList Close + ExecuteCommandLists + fence signal/wait

VulkanQueue now stores a VkDevice handle (with a TODO for lifetime
management) so it can create/destroy fences independently.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
MarijnS95 added a commit to Traverse-Research/offload-test-suite that referenced this pull request Apr 2, 2026
Move command buffer submission logic from each backend's Device into
Queue::submit(), which takes ownership of the command buffers. For now
it blocks internally until completion; a TODO marks that it will return
a Fence once the Fence abstraction from PR llvm#1007 is available.

- Metal: commit() + waitUntilCompleted()
- Vulkan: vkEndCommandBuffer() + vkQueueSubmit() with temporary fence + vkWaitForFences()
- DX12: CmdList::Close() + ExecuteCommandLists() + Queue::Signal()/Fence::SetEventOnCompletion() wait

VulkanQueue now stores a VkDevice handle (with a TODO for lifetime
management) so it can create/destroy fences independently.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
MarijnS95 added a commit to Traverse-Research/offload-test-suite that referenced this pull request Apr 2, 2026
Move command buffer submission logic from each backend's Device into
Queue::submit(), which takes ownership of the command buffers. For now
it blocks internally until completion; a TODO marks that it will return
a Fence once the Fence abstraction from PR llvm#1007 is available.

- Metal: commit() + waitUntilCompleted()
- Vulkan: vkEndCommandBuffer() + vkQueueSubmit() with temporary fence + vkWaitForFences()
- DX12: CmdList::Close() + ExecuteCommandLists() + Queue::Signal()/Fence::SetEventOnCompletion() wait

VulkanQueue now stores a VkDevice handle (with a TODO for lifetime
management) so it can create/destroy fences independently.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

4 participants