Description
D3D12 has an interesting command: SetGraphicsRootSignature.
In WebGPU terms, that would be equivalent to something like setPipelineLayout(required GPUPipelineLayout layout)
.
It's documented that an application have to set the root signature before doing a draw call, doesn't matter if it's done before or after the pipeline setup.
Here is what particularly worries me:
If a root signature is changed on a command list, all previous root arguments become stale and all newly expected arguments must be set before Draw/Dispatch otherwise behavior is undefined. If the root signature is redundantly set to the same one currently set, existing root signature bindings do not become stale.
Perhaps, we could get some clarification from Microsoft about the "behavior is undefined" part? I.e. why it's undefined, and what happens under the hood.
Since WebGPU user doesn't have direct access to this SetGraphicsRootSignature
, the user agent has one of the following options:
Option-1
Set the root signature on the pipeline change (setPipeline
). Re-bind all the resources in bind groups at this point.
This option has a problem: it makes setPipeline
performance difficult to reason about. It would be lightweight on Vulkan/Metal but very heavy on D3D12, and only when the pipeline layout is changing.
Note: On Vulkan specifically, we also nave to re-bind a portion of the pipeline layout, based on the layout compatibility rules.
At least it's possible to control the costs of it: if I know that my pipelines' layouts are only different in bind group number 3, then I can be assured that bind groups 0, 1, and 2 aren't going to be rebound internally when I do the pipeline switch.
On D3D12, however, it appears that any minor change in the pipeline layout leads to a performance cliff.
Option-2
Don't bind any resources at setBindGroup
. Instead, lazily bind everything at draw call.
This option has a similar problem: it's difficult to reason about the cost of setBindGroup
and draw
when any lazy binding is taking place. It puts DX12 at disadvantage, since Vulkan and Metal draw calls aren't encumbered by the lazy state.