-
Notifications
You must be signed in to change notification settings - Fork 386
Add a small document about the submission model #100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| # Command Submission | ||
|
|
||
| Command buffers carry sequences of user commands on the CPU side. | ||
| They can be recorded independently of the work done on GPU, or each other. | ||
| They go through the following stages: | ||
|
|
||
| creation -> "recording" -> "ready" -> "executing" -> done | ||
|
|
||
| Command buffers are created from and submitted to a command queue. | ||
| Creation and submission do not have to follow the same order. | ||
| The queue is also used to signal fences, allowing the user to know when the command buffers are done. | ||
|
|
||
| ## Detailed Model | ||
|
|
||
| Users issue rendering and compute commands (such as resource bindings, draw calls, etc) via command buffers. | ||
| The concept of `WebGPUCommandBuffer` matches the native graphics APIs. | ||
| Those command buffers go through the following stages in their life cycle. | ||
| It starts with creating a new `WebGPUCommandBuffer` from a `WebGPUCommandQueue` instance. | ||
| From this point, the command buffer is considered to be in "recording" state. | ||
|
|
||
| Commands can be encoded independent of anything done on `WebGPUDevice` or the underlying GPU. | ||
| The recording is CPU-only operation, and multiple command buffers can be recorded independently on web workers. | ||
| (TODO: disallow recording multiple command buffers on the same thread/web worker?). | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unless I am missing something I do not see why we would disallow recording multiple command buffers on the same thread/web worker.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The case in question is when the user has multiple command buffers in "recording" state on the same thread at a time. This is hardly a case used often. IIRC, D3D12 command pool disallows that explicitly (but multiple pools can be used). |
||
| Recording usually consists of a number of passes, be it render or compute, with occasional copy operations inserted between them. | ||
|
|
||
| Since a programmable pass defines the resource binding scope, synchronization rules, fixes the resource usage, and exposes a number of specific operations, we encapsulate the encoder of a pass into a separate object, such as `WebGPURenderPassEncoder` and `WebGPUComputePassEncoder`. | ||
| The pass encoder object can be obtained from a command buffer by calling `beginRenderPass` or `beginComputePass` correspondingly. | ||
| The command buffer is expected to be in "recording" state, or otherwise a synchronous error is triggered. | ||
| No operations may be done on the `WebGPUCommandBuffer` if there is an open pass being encoded to it. | ||
| Calling any methods on the command buffer with an open pass, or submitting it to the command queue, triggers a synchronous error. | ||
| A pass encoding consists of state setting code and draw/dispatch calls, which are all methods on the corresponding encoder object. | ||
| In order to close a pass, the user calls `WebGPUProgrammablePassEncoder::endPass`, which returns the owner `WebGPUCommandBuffer` object. | ||
| Passes cannot straddle command buffers, and a command buffer may contain multiple passes. | ||
|
|
||
| In order to finish recording a command buffer, the user calls `WebGPUCommandBuffer::finish` method, which transitions it from "recording" to the "ready" state. | ||
| It is valid to transfer this object between web workers. | ||
| When "ready", a command buffer can only be submitted for execution via `WebGPUCommandQueue::submit`, and no recording operations are available. | ||
| This method gets a sequence of command buffers and submits them (in the given order) to the GPU driver. | ||
| There are a few hidden (from the user point of view) stages here before the command buffer actually reaches the GPU. | ||
|
|
||
| Once submitted, the command buffer switches to "executing" state, which means the command buffer will execute (both on the CPU and GPU) in finite time. | ||
| If the WebGPU implementation fails to submit the command buffer due to a problem with recorded content (e.g. exceeding the limit for the instance count in a draw call), it is turned into an internally null object, and the asynchronous error is reported. | ||
| The feature to re-use command buffers for multiple submissions is still being discussed, and until this is clear, we consider the `WebGPUCommandBuffer` to be moved into submission. | ||
| Any operations on a command buffer in the "executing" state, other than dropping it (which is what the user is expected to do), would trigger a synchronous error. | ||
|
|
||
| If the submission is successful, then at some point in time the GPU will be done processing it. | ||
| The WebGPU implementation takes the responsibility to detect this moment and gracefully recycle/destroy this command buffer, when it's safe to do so. | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like there should be a loop here between
readyandrecording