1# Pipeline Compilation 2 3Vulkan pipelines depend on a number of state, most of which is known only at draw time. 4Unfortunately, creating pipelines is a heavy operation (in particular, converting SPIR-V to assembly 5and optimizing it), and doing so at draw time has multiple draw backs, including visible hitching. 6 7The first step taken towards alleviating this issue is to maximize ANGLE's use of available dynamic 8state. This allows ANGLE to create fewer pipelines. Simultaneously, ANGLE keeps the number of 9specialization constants to a minimum, to avoid recreating pipelines on state that might 10realistically change during the lifetime of the application. 11 12At link time, ANGLE warms up the pipeline cache by creating a few placeholder pipelines, in the hope 13that at draw time the pipeline cache is hit. Without `VK_EXT_graphics_pipeline_library`, this is 14hit-or-miss. With that extension though, ANGLE is able to create pipelines with less visible 15overhead. This document focuses on ANGLE's use of `VK_EXT_graphics_pipeline_library`. 16 17Note that `VK_EXT_graphics_pipeline_library` divides the pipeline in four stages: 18 19- Vertex Input 20- Pre-Rasterization Shaders 21- Fragment Shader 22- Fragment Output 23 24In ANGLE, the two shaders subset are currently always created together. 25 26## At Link Time 27 28At link time, one pipeline library corresponding to the shader stages is pre-created. Based on 29existing specialization constants and unavailability of some dynamic state, multiple variations of 30this pipeline library is created. This helps warm the pipeline cache, but also allows ANGLE to pick 31these pipelines directly at draw time. The pipelines are hashed and cached in the program 32executable. 33 34## At Draw Time 35 36At draw time, the vertex input and fragment output pipeline libraries are created similarly to how 37full pipelines are created, complete with hashing and caching them. The cache for these pipelines 38is independent of the program executable. 39 40Then, the shaders pipeline is retrieved from the program executable's cache, and linked with the 41vertex input and fragment output pipelines to quickly create a complete pipeline for rendering. 42Note that creating vertex input and fragment output pipelines is relatively cheap, and as they are 43shared between programs, there are also few of them. 44 45Unfortunately, linked pipelines may not be as efficient as complete pipelines. This largely depends 46on the hardware and driver; for example, some drivers optimize the vertex shader based on the vertex 47input, or implement the fragment output stage as part of the fragment shader. To gain back the 48efficiency of the pipeline, ANGLE uses background threads to compile monolithic pipelines with all 49the necessary state. Once the monolithic pipeline is ready, it's handle is swapped with the linked 50pipeline. 51 52The thread monolithic pipeline creation is orchestrated by the share group. Currently, only one 53pipeline creation job is allowed at a time. Additionally, posting these jobs is rate limited. This 54is primarily because the app is functional with reasonable efficiency with linked pipelines, so 55ANGLE avoids racing to provide monolithic pipelines as fast as possible. Instead, it ensures 56monolithic pipeline creation is inconspicuous and that it interferes as little as possible with the 57other threads the application may be running on other cores. 58 59To achieve this, each `PipelineHelper` whose handle refers to a linked pipeline holds a monolithic 60pipeline creation task to be scheduled. Every time the pipeline handle is needed (i.e. at draw 61time, after a state change), `PipelineHelper::getPreferredPipeline` attempts to schedule this task 62through the share group. The share group applies the aforementioned limits and may or may not post 63the task. Eventually, future calls to `PipelineHelper::getPreferredPipeline` would end up 64scheduling the task and observing its termination. At that point, the previous handle (from linked 65pipelines) is replaced by the handle created by the thread (a monolithic pipeline). 66