| # Threading in Vulkan | |
| The Vulkan backend uses a dedicated concurrent worker pool that is created along | |
| with the creation of the Vulkan context. | |
| Unlike other pools such as the IO worker pool, long running tasks may **not** be | |
| posted to this pool. This is because frame workloads can and often are | |
| distributed to workers in this pool. Having a potentially long running task | |
| (such as texture decompression) may potentially block frame critical tasks. The | |
| limitation of a separate pool for frame critical tasks is working around the | |
| separate limitation of not being able to specify a QoS to specific tasks and may | |
| be lifted in the future. | |
| There is also a separate component called the fence waiter which operates on its | |
| own thread. The purpose of the fence waiter is to ensure that the resource | |
| reference count lives at least as long as the GPU command buffer(s) that access | |
| this resource. | |
| Resource collection and pooling also happens on another thread called the | |
| resource manager. This is because touching the allocators is a potentially | |
| expensive operation and having the collection be done in a frame workload, or on | |
| the fence waiter thread may cause jank. | |
| With this overview, the total number of thread used by the Impeller Vulkan | |
| backend is the number of workers in the concurrent worker pool, and the two | |
| threads for the fence waiter and resource manager respectively. | |
| A summary of the interaction between the various threads is drawn below: | |
| ```mermaid | |
| sequenceDiagram | |
| participant rt as Render Thread | |
| participant worker1 as Concurrent Worker 1 | |
| participant worker2 as Concurrent Worker 2 | |
| participant fence_waiter as Fence Waiter | |
| participant resource_manager as Resource Manager | |
| participant gpu as GPU | |
| rt->>+worker1: Setup PSO 1 | |
| rt->>+worker2: Setup PSO n | |
| worker1-->>-rt: Done | |
| worker2-->>-rt: Done | |
| Note over rt,resource_manager: Application launch | |
| loop One Frame | |
| activate rt | |
| rt->>+worker2: Frame Workload | |
| activate fence_waiter | |
| rt->>fence_waiter: Resource 1 owned by GPU | |
| worker2-->>-rt: Done | |
| rt->>fence_waiter: Resource 2 owned by GPU | |
| rt->>gpu: Submit GPU Commands | |
| deactivate rt | |
| end | |
| activate gpu | |
| gpu-->>fence_waiter: GPU Work Done | |
| fence_waiter->>resource_manager: Collect/Pool Resources | |
| deactivate fence_waiter | |
| activate resource_manager | |
| deactivate gpu | |
| deactivate resource_manager | |
| ``` |