Intro

Requirements:

  • have resources that can be used on queues A and B, but not simultaneously
  • initialized on A, then read in B (requires ownership transfer)
  • reset in A (doesn't require transfer)
  • resource is initialized in A, but then used in B and C

There are resources that are "shareable" between all queues (VK_SHARING_MODE_CONCURRENT),
and ones that need to be transferred (VK_SHARING_MODE_EXCLUSIVE).
The former prevents color compression, hence slow!
The latter doesn't allow a resource to be read by multiple queues

In order for a resource to be used on a different queue,
there needs to be a couple of matching pipeline barriers submitted to the queues. But only if the resource contents need to be preserved(!).

Command buffers are created by the queue instead of the device, and can only be submitted on this queue.

Vulkan Note: the transfers are only needed between queue families internally. Queues within the same family can all access a resource as if it is concurrent.

Proposal-1

When creating a resource, user provides a list of queues that the resource can be accessed from.
If used on more than one queue, it's created with VK_SHARING_MODE_CONCURRENT internally.
By default, resources can only be used on the first (default) queue.

Proposal-2

All resources are created with VK_SHARING_MODE_EXCLUSIVE flag.
On the device timeline, we associate each resource with a queue that currently owns it.
On submission, if there are any resources that were previously used on a different queue,
and the new usage doesn't re-initialize them completely, we:

  1. submit a special "release" command buffer (alone) that does the "release" pipeline barriers from each source queue.
    This submit is done with a semaphore.
  2. prepend a command buffer that does all the "acquire" pipeline barriers to the current submission
  3. submit it with the semaphore waits for all the source queues

Proposal-2a

(extends Proposal-2)

The CommandBufferDescriptor (provided to CommandEncoder::finish()) can have
a list of resources that are "released" from the queue. For each, the destination queue is specified.
At the end of encoding, we insert all the corresponding "release" pipeline barriers to this command buffer, before closing it.

If a command buffer releases any resources, it will be submitted with signaling of a semaphore.

The rest is the same as in Proposal-2, but without automatic "release".