Skip to content

Problem with the default queue #1977

Closed
Closed

Description

@kvark

@pythonesque pointed out that having the default queue on the device is causing a few issues.

First, it introduces a circular dependency. Device points to a queue, but a queue is owned by the device. Resources, owned by a device, submitted in command buffers to a queue, are held alive by the queue for the duration of GPU use of them. So "Resource <- Queue <- Device" and "Resource -> Device".

Arguably, this is an implementation issue. Generally, however, designing a structure of classes without (or with minimum) circular dependencies could be considered a better design.

Secondly, in the multi-queue world, it would harm the ability of users to control what's happening on the queues. Since the queue argument isn't participating directly, it's used implicitly, and it makes it more difficult to reason about the queue loads.

The list of operations that currently depend on the default queue:

  1. command encoder creation - Associate command encoding with a queue #1278
  2. unmapping of buffers created with "mappedAtCreation". A queue needs to do a copy operation from the staging area into the GPU memory of such buffer.
  3. maybe something is missing in this list?

Activity

  1. kainino0x commented on Jul 21, 2021

    @kainino0x
    Contributor
    • unmapping of buffers created with "mappedAtCreation". A queue needs to do a copy operation from the staging area into the GPU memory of such buffer.

    Depending on how we model mapping wrt queue transfers, I'm not sure whether this is a problem. FWIW I think it also applies to mapAsync?

    • If mapping is a transfer to the CPU "queue", then at some point there will be a transfer back to a GPU queue. Maybe the copy can happen on that queue (but with implicit transfers maybe that's a bit late).
    • If mapping leaves the buffer associated with its current queue (and resources probably start on a particular queue), the copy would naturally happen on the still-current queue, on unmap.
    • I wonder if these staging buffer copies could happen on an internal copy-only queue?
  2. kvark commented on Jul 21, 2021

    @kvark
    ContributorAuthor

    FWIW I think it also applies to mapAsync?

    No, I don't think so. Mapping buffers generally involves copying shared memory around on CPU (into mapped native staging buffers), it doesn't involve any actual queue operations.

    If mapping is a transfer to the CPU "queue", then at some point there will be a transfer back to a GPU queue. Maybe the copy can happen on that queue (but with implicit transfers maybe that's a bit late).

    For this, we'd need to know the queue at unmap() time. @pythonesque suggested to add a queue parameter there.

    I wonder if these staging buffer copies could happen on an internal copy-only queue?

    Maybe on D3D12 and a fraction of Vulkan devices, but doesn't look portable.

  3. Kangz commented on Jul 22, 2021

    @Kangz
    Contributor

    In one of the multi queue proposals: #1073 I suggested aGPUUnmapOptions optional argument to unmap. While we don't need to add it now in the spec because it would be backwards compatible, I think we should have something in webgpu.h to prepare for when we need options.

  4. litherum commented on Aug 2, 2021

    @litherum
    Contributor

    GPUUnmapOptions makes sense to me.

  5. added this to the MVP milestone on Aug 23, 2021
  6. Kangz commented on Dec 15, 2021

    @Kangz
    Contributor

    We'll remember to do something about this when we do multiqueue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions