## Multiple GPU Queues
<!--
Expose more than a single GPU queue:
  - investigation: https://github.com/gpuweb/gpuweb/issues/1065
  - proposal-1: https://github.com/gpuweb/gpuweb/issues/1066
  - proposal-2: https://github.com/gpuweb/gpuweb/issues/1073
-->

[Expose API]: We should expose multiple queues with different capabilities.
  + <API Support>: Common across all three APIs
               (Metal starting with version 2, where `MTLEvent` got introduced).
  + <Performance>: Async compute and transfers are established best practices on
                   the last-gen console hardware (PS4 and XB1).
                   See [AMD presentation](https://gpuopen.com/wp-content/uploads/2017/03/GDC2017-Asynchronous-Compute-Deep-Dive.pdf).
  + <Viable>: Investigation showed that we can safely track the ownership of resources
              by the queues, and insert the necessary pipeline barriers, making this safe.
  +> [Implicit Transitions]
  +> [Required Transitions]

[Fully Internal]: WebGPU should internally use multiple queues but not necessarily
                  expose them to the user.
  + <Simple>: Simplest to use.
  - <Ineffective>: WebGPU doesn't know resource dependencies ahead of time, so finding
                   the efficient scheduling route is hard. It's likely to synchronize
                   more than necessary.
  + <Metal>: this is what Metal-1 does in the drivers/run-time.
  -> [Expose API]

[Implicit Transitions]: Ownership transition can happen automatically, based on resources
                        that are used by submissions.
  + <Easy>: Code will always work, just not always be concurrent on GPU, even if
            the developer submits work to different queues.
  +> [WebGPU doesn't need fences]

[WebGPU doesn't need fences]: Fences are technically not needed in the API and can be removed?

[Optional Transitions]: Allow the developer to specify an ownership transition ahead of time.
  +> [Implicit Transitions]

[Required Transitions]: Require the developer to transition ownership explicitly.
  + <Explicit>: Allows the developer to reason about concurrent GPU processing.
                Since the developers are not required to use the multiple queues,
                they want to be sure it works as expected if they do use it.
  - <Racy>: Changing the order of submissions may result in a synchronization error.
            If submissions are triggered by external events (e.g. touch), this
            may be a hidden even race and a footgun in an otherwise correct application.
    - <Logic>: If the order of submission is unexpected, that would likely end up with
               incorrect rendering anyway. So maybe it's fine to disallow that?
  -> [Optional Transitions]

<Skip Submit>: on Vulkan, we can avoid submitting an empty command buffer with the
               semaphore and a pipeline barrier.
  +> [Optional Transitions]
  +> [Required Transitions]

[Concurrent Textures]: We should support textures that are used concurrently on multiple queues.
  + <Texture Support>: At least D3D12 and Vulkan have explicit opt-in for this behavior.
  - <Cost>: There are clear pefromance costs for having this ability on a texture. It's not able
            to use specific texture states and layouts, and can't use color compression.
Argument Map cluster_1 Multiple GPU Queues n0 Expose API We should expose multiple queues with different capabilities. n1 Implicit Transitions Ownership transition can happen automatically, based on resources that are used by submissions. n0->n1 n2 Required Transitions Require the developer to transition ownership explicitly. n0->n2 n4 WebGPU doesn't need fences Fences are technically not needed in the API and can be removed? n1->n4 n5 Optional Transitions Allow the developer to specify an ownership transition ahead of time. n2->n5 n3 Fully Internal WebGPU should internally use multiple queues but not necessarily expose them to the user. n3->n0 n5->n1 n6 Concurrent Textures We should support textures that are used concurrently on multiple queues. n7 API Support Common across all three APIs (Metal starting with version 2, where `MTLEvent` got introduced). n7->n0 n8 Performance Async compute and transfers are established best practices on the last-gen console hardware (PS4 and XB1). See AMD presentation. n8->n0 n9 Viable Investigation showed that we can safely track the ownership of resources by the queues, and insert the necessary pipeline barriers, making this safe. n9->n0 n10 Simple Simplest to use. n10->n3 n11 Ineffective WebGPU doesn't know resource dependencies ahead of time, so finding the efficient scheduling route is hard. It's likely to synchronize more than necessary. n11->n3 n12 Metal this is what Metal-1 does in the drivers/run-time. n12->n3 n13 Easy Code will always work, just not always be concurrent on GPU, even if the developer submits work to different queues. n13->n1 n14 Explicit Allows the developer to reason about concurrent GPU processing. Since the developers are not required to use the multiple queues, they want to be sure it works as expected if they do use it. n14->n2 n15 Racy Changing the order of submissions may result in a synchronization error. If submissions are triggered by external events (e.g. touch), this may be a hidden even race and a footgun in an otherwise correct application. n15->n2 n16 Logic If the order of submission is unexpected, that would likely end up with incorrect rendering anyway. So maybe it's fine to disallow that? n16->n15 n17 Skip Submit on Vulkan, we can avoid submitting an empty command buffer with the semaphore and a pipeline barrier. n17->n2 n17->n5 n18 Texture Support At least D3D12 and Vulkan have explicit opt-in for this behavior. n18->n6 n19 Cost There are clear pefromance costs for having this ability on a texture. It's not able to use specific texture states and layouts, and can't use color compression. n19->n6