Skip to content

feat(vulkan): allow specifying queue family ownership transfer in texture barriers#9668

Open
alexander-bruun wants to merge 1 commit into
gfx-rs:trunkfrom
alexander-bruun:feat/2948-vulkan-queue-family-ownership-transfer
Open

feat(vulkan): allow specifying queue family ownership transfer in texture barriers#9668
alexander-bruun wants to merge 1 commit into
gfx-rs:trunkfrom
alexander-bruun:feat/2948-vulkan-queue-family-ownership-transfer

Conversation

@alexander-bruun

Copy link
Copy Markdown

Connections

Resolves #2948.

Description

Adds an optional queue_family_ownership_transfer field to hal::TextureBarrier so textures imported from external memory can be acquired from / released back to a sentinel queue family. Honored only by the Vulkan backend (sets src/dstQueueFamilyIndex on the image barrier); all other backends ignore it. When None (every existing caller) the indices default to VK_QUEUE_FAMILY_IGNORED, so behavior is unchanged.

Also exposes hal::QUEUE_FAMILY_{IGNORED,EXTERNAL,FOREIGN} sentinels so callers don't need a direct ash dependency.

Testing

  • cargo check -p wgpu-hal --features vulkan --all-targets and cargo check -p wgpu-core --features vulkan.
  • Unit test asserting the sentinels match the Vulkan values, plus a compile-time assertion against ash.

Squash or Rebase?

Single commit, ready to rebase onto trunk as-is.

…ture barriers

Images imported from external memory must have their backing image's queue
family ownership transferred from a sentinel queue family (FOREIGN/EXTERNAL)
to wgpu's queue family on acquire, and transferred back on release. The
Vulkan HAL previously built image memory barriers without ever setting
src/dst queue family indices, so this was impossible to express.

Add an optional `queue_family_ownership_transfer` field to the
backend-agnostic `hal::TextureBarrier`. It is honored only by the Vulkan
backend (which now sets `src/dstQueueFamilyIndex` on the
`VkImageMemoryBarrier`); all other backends ignore it. When unset, both
indices default to `VK_QUEUE_FAMILY_IGNORED`, preserving existing behavior.

Expose `hal::QUEUE_FAMILY_{IGNORED,EXTERNAL,FOREIGN}` sentinels (with a
compile-time assertion that they match ash's values) so callers using
`vulkan::Device::queue_family_index()` can build acquire/release transfers
without depending on ash directly.

Resolves gfx-rs#2948.
@alexander-bruun alexander-bruun force-pushed the feat/2948-vulkan-queue-family-ownership-transfer branch from 8169962 to 984d3f0 Compare June 13, 2026 18:43
@inner-daemons

Copy link
Copy Markdown
Collaborator

CC @atlv24 :)))

As for this PR, we actually plan to implement multiqueue ourselves so QFOTs would be part of that. As for now this is only an unsafe hal interop thing for one API, I would be agaInst putting it in a normal wgpu api like barriers. Finally, even if this were correct, it would probably have to be implemented for all barriers.

Happy to discuss this further, I think there is some way to make this work before multiqueue lands.

@inner-daemons inner-daemons self-requested a review June 14, 2026 05:01
@inner-daemons inner-daemons self-assigned this Jun 14, 2026
@cwfitzgerald cwfitzgerald self-assigned this Jun 24, 2026

@cwfitzgerald cwfitzgerald left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for working on this! Some comments

Comment on lines +10 to +17
// The backend-agnostic queue family sentinels in `crate` must match the Vulkan
// values they stand for, since they are passed straight through to ash.
const _: () = {
assert!(crate::QUEUE_FAMILY_IGNORED == vk::QUEUE_FAMILY_IGNORED);
assert!(crate::QUEUE_FAMILY_EXTERNAL == vk::QUEUE_FAMILY_EXTERNAL);
assert!(crate::QUEUE_FAMILY_FOREIGN == vk::QUEUE_FAMILY_FOREIGN_EXT);
};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This seems like unnecessary coupling, we can have a mapping function from an enum in the transition struct to the vulkan ones.

Comment thread wgpu-hal/src/lib.rs
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct QueueFamilyOwnershipTransfer {
/// The queue family that currently owns the image (`srcQueueFamilyIndex`).
pub src: u32,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we can have an enum with variants for ignored/external/foreign, then a variant with like Explicit(u8) or something

Comment thread wgpu-hal/src/lib.rs
Comment on lines +2611 to +2613
/// Special queue family value indicating that no ownership transfer should be
/// performed (`VK_QUEUE_FAMILY_IGNORED`).
pub const QUEUE_FAMILY_IGNORED: u32 = u32::MAX;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

When we have an optional queue family transition, does this variant actually make sense to have, wouldn't you use None

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.

Vulkan hal should allow specifying what memory barriers to insert for custom textures

3 participants